Skip to main content

More Literate Programming with jMock: Anaphora

Posted by tomwhite on May 14, 2006 at 2:30 AM PDT

According to the dictionary, an anaphor is a word used to avoid repetition. It refers back to something in the conversation. The word "it" in the previous sentence refers back to the word "anaphor" in the first sentence, so "it" is an anaphor for "anaphor". Natural language is often ambiguous, and one reason for this is that it may not be clear which word an anaphor such as "it" is referring to.

But ambiguity and programming languages don't go very well together - so why would anyone want to mix the two? Actually, there are circumstances in programming languages where there is no real ambiguity, and an anaphor can have a use in eliminating repetition. Think of it as applying the DRY (Don't Repeat Yourself) principle at the syntax level.


We introduced a limited form of anaphora in the functional test framework I talked about in my previous blog entry, Literate Programming with jMock. Consider some more sample code:

public void testMainMenu() throws Exception {

    assertThat(theCurrentPage, has(title("Home Menu")));
    assertThat(it, has(menuOptions().named("Departures and Arrivals",
                                           "Travel News")));

The variable it refers to the object that was the target of the assertThat call on the previous line; in this case the current page referred to by the theCurrentPage variable. We improve readability and remove multiple references to theCurrentPage, without compromising ambiguity (and therefore without the risk of introducing bugs).

So where does the the variable it come from? We created a subclass of org.jmock.MockObjectTestCase, and added a protected instance variable called it of type Object, then overrode the assertThat method to stash away the target object:

public void assertThat(Object target, Constraint constraint) {
    it = target;
    super.assertThat(target, constraint);

That's it.

Temporary Local Variables

The biggest gain is the case where you can avoid having to create a temporary local variable. You often want to assert several things about an object, so you end up creating a local variable with a short name to refer to the target object:

public void test() {
    Fruit fruit = lunchbox.getFruit();
    assertThat(fruit, isNotNull());
    assertThat(fruit, hasProperty("colour", eq("yellow")));
    assertThat(fruit, isIn(lunchbox.getItems()));

Alternatively, you can use the and constraint to make a single assertion, but this is less readable and is hard to format well:

public void test() {
            hasProperty("colour", eq("yellow")),

Using it produces the most readable test:

public void test() {
    assertThat(lunchbox.getFruit(), isNotNull());
    assertThat(it, hasProperty("colour", eq("yellow")));
    assertThat(it, isIn(lunchbox.getItems()));

Our experience has been that the little bit of syntactic sugar that it provides is convenient, and not at all ambiguous.

Related Topics >>