Mocks are hip when it comes to BDD - No Fluff Just Stuff

Mocks are hip when it comes to BDD

Posted by: Andrew Glover on July 3, 2007

I must admit that I rarely spend too much time with Mock objects– I have found in many scenarios that these handy objects get abused and in a few situations, completely invalidate the tests they were designed to facilitate. Plus, with myriad JUnit extension frameworks available, I’ve often found that testing is easier without mocks– for instance, why bother mocking out a data layer when you can just bite the bullet and control the underlying database via DbUnit?

Since attending CITCON last April, however, I’ve been digging deeply into Behavior Driven Development or BDD. If you aren’t familiar with this hip term, don’t fear, it’s rather intuitive and is easy to grasp. Briefly, BDD attempts to provide a common vocabulary that facilitates collaboration between business stake holders and those individuals who take requirements and turn them into working code (something that Fit also attempts to manage). What’s interesting about BDD is that the word “test” essentially disappears– rather than thinking in terms of testing, BDD shifts the focus to behavior or what the system should do.

Interestingly, following this paradigm, code that is used to verify functionality becomes human readable. Don’t get me wrong, by the way, you can make JUnit tests quite readable too; in fact, it is certainly a copasetic practice to name one’s test cases descriptively, such as testFindAllReturnsTwoPersons. But the fact of the matter is that with JUnit (and associated frameworks) you are, in essence, forced to think in terms of testing (regardless if you actually have to name the test case with test– annotations in JUnit 4 and TestNG facilitate flexible naming, man).

Once you accept BDD as a way of thinking, an intriguing thing happens– mocks become quite attractive in the early design a system. Of course, mocks are useful in this context without BDD, TDD, or any other methodology, but the point being, when thinking of behavior, you are forced to think in terms of isolation and interfaces. And because I’m thinking about behavior, I’m not focused on testing (which for some odd reason, appears to be a jive turkey word to developers far too often in my experience).

For example, imagine, because it’s your bag, you’ve been hired to develop an astronomy application for students to explore the relationship between planets and their associated moons (or satellites). In this application, a planetary system can have a collection of moons, each having a series of properties relating to radius, orbital period, and distance from a planet. You can ask a particular planetary system for its closest moon, the fastest orbiting moon, and the biggest moon, to name a few features. The goal of these features is to allow students to understand the relationship between satellite properties and how they affect orbital speeds, etc (for instance, what hip factor contributes to a faster orbital speed?).

Given this high level description, you could potentially flesh out a simple model consisting of two interfaces, namely a PlanetarySystem and a Moon.

public interface IPlanetarySystem {
  IMoon fastestOrbitingSatellite();
  IMoon closestSatellite();
}

For now, the IPlanetarySystem interface exposes two features and, as you can see, man, a moon has a series of properties one can request.

public interface IMoon {
  String getName();
  double getOrbitPeriod();
  double getDistanceFromPlanet();
  double getRadius();
}

As a first pass, I could begin to mock out each object and start to specify behavior, using, for example, the JBehave BDD framework (which also happens to bundle a mocking framework known a Minimock). In fact, using JBehave, I can use its Story framework and flesh out a few details, however, that’s a whole other article. Let’s say I’ve done that and in the process, determined that in order to provide the functionality, for instance, to find the closet satellite, I’ll need to create some Comparator types which will facilitate sorting in a collection. Given that I’ve done that, using BDD, I begin to think in terms of given some context, when something happens, then the system should do something in response.

In the case of obtaining the fastest orbiting satellite:

  • given a planet has more than one satellite
  • when a student requests the fastest orbiting satellite
  • then the system should return the moon whose orbital period is the shortest

Rather than mock out the IPlanetarySystem object, by this point, I can start to actually create an implementation of it. In fact, I’ll focus on the fastestOrbitingSatellite method, which will sort a given collection of IMoons by each moon’s orbital period.

public IMoon fastestOrbitingSatellite() {
  IMoon[] sortable = this.getSortableType();
  Arrays.sort(sortable, Moon.OrbitPeriodComparator);
  return sortable[0];
}

The getSortableType method is a convenience method that was created with the foresight that any sorting style method will need to convert a Collection to an array as shown below.

private IMoon[] getSortableType(){
  return (IMoon[])this.moons.toArray(new IMoon[this.moons.size()]);
}

I’d like to verify this behavior, but I haven’t actually created a concrete IMoon object yet other than an anonymous Comparator inner class– Moon.OrbitPeriodComparator, which looks like this:

public static Comparator<IMoon> OrbitPeriodComparator = new Comparator<IMoon>(){
  public int compare(IMoon o1, IMoon o2) {
   if(o1.getOrbitPeriod() == o2.getOrbitPeriod()){
    return 0;
   }else if(o1.getOrbitPeriod() > o2.getOrbitPeriod()){
    return 1;
   }else{
    return -1;
  }
 }
};

Using JBehave’s UsingMiniMock class, I can verify the concrete IPlanetarySystem’s behavior quite easily and keep on truckin’ with a full range of mocking at my disposal. JBehave functions much like JUnit, but instead of each test case starting with “test” a behavioral method starts with “should”– there is also the notion of fixtures via setUp. In my case, I’d like to create a collection of Moon objects, specifically mock moons because I haven’t actually created a concrete instance and I’d like to explore a little bit to ensure I indeed like the intended behavior between a planetary system and a moon.

public class PlanetarySystemBehavior extends UsingMiniMock {

  private PlanetarySystem system;

  public void setUp(){
    IMoon io = this.getMockMoon("Io", 1.77, 422000);
    IMoon eur = this.getMockMoon("Europa", 3.55, 671000);
    IMoon gan = this.getMockMoon("Ganymede", 7.15, 1070000);

    List<IMoon> moons = Arrays.asList(io, eur, gan);

    this.system = new PlanetarySystem("Jupiter", moons);
  }
}

Thus far, because it’s my bag, I’ve created a Behavior class (via JBehave) that creates a List of IMoons via a getMockMoon method, which handles the nitty gritty of mocking.

private IMoon getMockMoon(String name, double orbitalPeriod, double distance){
 Mock moon = mock(IMoon.class);
 moon.stubs("getName").withNoArguments().will(returnValue(name));
 moon.stubs("getOrbitPeriod").withNoArguments().will(returnValue(new Double(orbitalPeriod).doubleValue()));
 moon.stubs("getDistanceFromPlanet").withNoArguments().will(returnValue(new Double(distance).doubleValue()));
 return (IMoon)moon;
}

As you can see, Minimock is easy to grasp– I create a mock instance of my interface (IMoon) and then specify the return values for desired methods. In my case, for example, I can specify that the getOrbitPeriod method, when called with no arguments, will return a double value. I then cast the mock into the interface type and return it to the caller so as to avoid any casts later in the process. What a trip!

Now I can verify behavior with a simple method.

public void shouldReturnFastestSatellite() throws Exception{
 IMoon moon = this.system.fastestOrbitingSatellite();
 ensureThat(moon.getName(), eq("Io"));
}

Note how the method above reads in an agreeable manner– when a student asks for the fastestOrbitingSatellite, the system should return the moon whose orbital period is shortest– in this case, I’m ensuring that the moon’s name is equal to “Io” because I defined it with the shortest value (1.77 earth days).

The beauty of mocks, in this case, is that I’m able to ascertain hip behavior before I even flesh out a concrete class. What’s also helpful is that BDD, in essence, gets me thinking of behavior rather than tests. This difference then has me proactively thinking naturally and thus facilitates the usage of mocks not so much as testing objects but as fleshing out behavior of objects. I can always go back and replace the mocks with concrete objects too– in fact, this sort of iterative design liberates you to throw code away– once things are fleshed out, don’t use the mock– verify the behavior of the real tripping thing, man. And it is in the BDD paradigm that mocks are hip. Dig it?

Accelerate development space | I also blog at testearly.com
The Continuous Integration book | Groovy in Action

Andrew Glover

About Andrew Glover

Andrew is the Engineering Manager for Netflix's Delivery Engineering Team. He and his team are building the next generation Continuous Delivery platform that is facilitating Netflix's rapid global expansion. Before joining Netflix, he served as the CTO of App47, where he lead the development of a SaaS Mobile Application Management platform. Andrew is also the co-author of Addison Wesley's “Continuous Integration” and he actively blogs about software at thediscoblog.com.

Why Attend the NFJS Tour?

  • » Cutting-Edge Technologies
  • » Agile Practices
  • » Peer Exchange

Current Topics:

  • Languages on the JVM: Scala, Groovy, Clojure
  • Enterprise Java
  • Core Java, Java 8
  • Agility
  • Testing: Geb, Spock, Easyb
  • REST
  • NoSQL: MongoDB, Cassandra
  • Hadoop
  • Spring 4
  • Cloud
  • Automation Tools: Gradle, Git, Jenkins, Sonar
  • HTML5, CSS3, AngularJS, jQuery, Usability
  • Mobile Apps - iPhone and Android
  • More...
Learn More »