Mocking – What is it?

As many of you know, we have a couple of interns at our office this summer.  These guys (yes, they are all guys) have never done any testing before (they are in high school still) and I am rather passionate about testing my code.  So, being a good mentor (ok…so being a selfish person who knows that maintaining the software will fall to me and my team), I suggested that they learn about unit testing and begin applying it to the code they are writing.

As part of their learnings, the interns needed to learn about mock objects, what they are and why you need them.

What is a Mock?

Simply put, a mock object is a faked out version of an object.  You have complete control over what values are returned, and can interrogate it to see what values were passed into it.

Why would we want to do that?!

When writing unit tests, we should be constraining our tests to one method and one path through that method.  But, we know that when we are writing code, often our objects and methods need to access other objects and methods.  This leaves us in a conundrum.  How do we isolate our code?

Here’s a simple example.  Let’s say we have an object that can translate from several languages into English:

public class TranslatorFacade {
  private Translator klingonTranslator;
  private Translator spanishTranslator;

  public TranslatorFacade(Translator klingon, Translator spanish) {
    klingonTranslator = klingon;
    spanishTranslator = spanish;
  }

  public String translateFromKlingon(String phrase) {
    return klingonTranslator.translate(phrase);
  }
  public String translateFromSpanish(String phrase)...

In this example, we are creating a simple Facade that can call a bunch of different translators, but we are using the translator object directly.  We already have tests around each translator, so we don’t want to retest the translator here, but we want to make sure our facade is calling the right methods and is returning the right things.

How do we avoid retesting each translator then?  By mocking out the translators, of course!

Let’s give a short snippet of what that might look like if we wrote our own mock objects.  First, let’s assume we have an interface for translators which looks like this:

public interface Translator {
   public String translate(String phrase);
}

Then, in our test we could do something like this:

private class TestTranslator implements Translator {
  private String translatePhrase;
  private String phraseToReturn;
  public String translate(String phrase) {
    this.translatePhrase = phrase;
    return phraseToReturn;
  }
  public String translate_phrase() {
    return translatePhrase;
  }
  public void translate_return(String phraseToReturn) {
    this.phraseToReturn = phraseToReturn;
  }
}

// WARNING!  I DO NOT KNOW KLINGON
public testTranslateFromKlingon() {
  Translator klingon = new TestTranslator();
  klingon.translate_return("HORRAY");
  TranslatorFacade facade = new TranslatorFacade(klingon, new TestTranslator());
  String english = facade.translateFromKlingon("KA PLA");
  assertEquals("KA PLA", klingon.translate_phrase());
  assertEquals("HORRAY", english);
}

I know there is a lot of code up there.  But what I am trying to show is that we can easily make fake versions of our translators to capture the values that were sent into the object, as well as control the values that were returned from it.

This keeps us from re-testing our implementations when we are using the class somewhere else, which means that when we introduce an error, we are directed very precisely to where the issue is, rather than to all of the classes that happen to be using the failing method.

Seems like a lot of work

The above example is very simplistic.  Imagine that we needed to do something extra with the value that was returned from the translator in our method.  Perhaps we need to censor it or quote it.  We want to make sure that our censoring code is working as we expected.  By introducing mock objects, we can be sure that we are testing just that by setting our return values to strings that contain words that need censoring as well as ones that do not without having to know or understand the implementation of the translator class.

Let me state that again…because I think it is important.  By mocking the objects we are using, we don’t have to know or understand the implementation of the objects we are using!  Think about how many libraries you use in your day to day coding.  Being able to test your code without knowing the details of the code you are using is a big deal!

Do I have to write my own mocks?

No.  In fact, there are a lot of frameworks out there that will help you create mocks very easily.  Mockito and PowerMock are two that come to mind off the top of my head, and I know that there are many more out there.

Advertisements

One thought on “Mocking – What is it?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s