Testing in Java: Part II – Writing a Fake

In the first part we talked about the domain objects and how to test a domain object.  Now it’s time to look at how to persist them to an in-memory data store for testing purposes.  We’ll be writing this in such a way that at a later date you can replace the in-memory representation with a strategy that persists the data to disk.  So, let’s jump right into the code starting with the data access object interface.

package com.laneholloway.unittestingexample.database.dao;

import com.laneholloway.unittestingexample.domain.MyItem;

import java.util.UUID;

/**
 * A simple Data Access Object
 */
public interface MyDao {
    public boolean exists(UUID guid);
    public MyItem get(UUID guid);
    public boolean save(MyItem item);
    public void delete(UUID guid);
}

Looking at the code you can easily tell that there are some simple CRUD operations and an exists command. Any datasource that we want to write the data to must implement these commands and inside the program, we should only use these commands to interact with the object. In order to facilitate the testing of the framework, I’ve created a simple in memory dao and placed it into the test directory that maven creates.

package com.laneholloway.unittestingexample.database.dao;

import com.laneholloway.unittestingexample.domain.MyItem;

import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * An in-memory representation of a datastore using MyDao
 */
public class MyInMemoryDao implements MyDao {
    private Map<UUID, MyItem> storedItems;

    public MyInMemoryDao() {
        this.storedItems = new HashMap<UUID, MyItem>();
    }

    @Override
    public boolean exists(UUID guid) {
        return this.storedItems.containsKey(guid);
    }

    @Override
    public MyItem get(UUID guid) {
        return this.storedItems.get(guid);
    }

    @Override
    public boolean save(MyItem item) {
        this.storedItems.put(item.getGuid(), item);
        return true;
    }

    @Override
    public void delete(UUID guid) {
        this.storedItems.remove(guid);
    }
}

The in memory dao uses a Map to hold the MyItem elements. As you can tell, the implementation is straight-forward and doesn’t pull any punches. It does exactly what it needs to do in order for us to test other parts of the system that require the use of the MyDao interface. In order for the other Maven modules to use this test implementation, we have to do a little work in Maven to expose this as a test class. In the POM file relating to the doa-interface module, we add this bit which creates a test jar file.

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <executions>
                    <execution>
                        <goals>
                            <goal>test-jar</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

Now, using this test jar we can begin to test classes that use the MyDao interface. To use this test jar you modify the POM files for all modules that need access to this code with a dependency with it’s scope set to test.

In our case, we have the MyCommonInterface class which you’ll typically see in applications to give the consumers of the code a unified API to the CRUD operations abstracting away the DAO or DAOs that might make up the data storage of the application.

package com.laneholloway.unittestingexample.database.commoninterface;

import com.laneholloway.unittestingexample.domain.MyItem;

import java.util.UUID;

/**
 * A common interface to abstract away the various DAOs and allow the consumer of the API one interface to all
 * data.
 */
public interface MyCommonInterface {
    public boolean exists(UUID guid);
    public MyItem get(UUID guid);
    public boolean save(MyItem item);
    public void delete(UUID guid);
}

I’ve also supplied a simple implementation that uses a single DAO,

package com.laneholloway.unittestingexample.database.commoninterface;

import com.laneholloway.unittestingexample.domain.MyItem;
import com.laneholloway.unittestingexample.database.dao.MyDao;

import java.util.UUID;

/**
 * A very simple common interface
 */
public class MyCommonInterfaceForOneDao implements MyCommonInterface {
    private final MyDao dao;

    public MyCommonInterfaceForOneDao(MyDao myDao) {
        this.dao = myDao;
    }

    @Override
    public boolean exists(UUID guid) {
        return this.dao.exists(guid);
    }

    @Override
    public MyItem get(UUID guid) {
        return this.dao.get(guid);
    }

    @Override
    public boolean save(MyItem item) {
        return this.dao.save(item);
    }

    @Override
    public void delete(UUID guid) {
        this.dao.delete(guid);
    }
}

You can see that in the constructor, it expects a variable of type MyDao and then uses to perform CRUD operations. In order to properly test this, we need to use the in memory implementation so we don’t have to worry about creating a database, cleaning the database, and all the other database tasks needed just to test this interface. Using the this implementation, we can create a JUnit test class like this:

package com.laneholloway.unittestingexample.database.commoninterface;

import com.laneholloway.unittestingexample.database.dao.MyDao;
import com.laneholloway.unittestingexample.database.dao.MyInMemoryDao;
import com.laneholloway.unittestingexample.domain.MyItem;
import com.laneholloway.unittestingexample.domain.MyItemImpl;
import org.junit.Before;
import org.junit.Test;

import java.util.UUID;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

public class MyCommonInterfaceForOneDaoTest {
    private MyCommonInterfaceForOneDao myCommonInterfaceForOneDao;

    @Before
    public void setup() {
        MyDao myDao = new MyInMemoryDao();
        myCommonInterfaceForOneDao = new MyCommonInterfaceForOneDao(myDao);
    }

    @Test
    public void can_save_item() throws Exception {
        MyItem myItem = new MyItemImpl(UUID.randomUUID(),"Test Item");
        myCommonInterfaceForOneDao.save(myItem);
        assertTrue(myCommonInterfaceForOneDao.exists(myItem.getGuid()));
    }

    @Test
    public void can_delete_item() throws Exception {
        MyItem myItem = new MyItemImpl(UUID.randomUUID(),"Test Item");
        myCommonInterfaceForOneDao.save(myItem);
        myCommonInterfaceForOneDao.delete(myItem.getGuid());
        assertFalse(myCommonInterfaceForOneDao.exists(myItem.getGuid()));
    }
}

In the setup method, you can see that MyInMemoryDao is initialized and then injected into the MyCommonInterfaceForOneDao constructor which then allows these simple unit tests to be run verifying the correct operations. And with this, we’ve wrapped up the second section of the code, creating a data access layer that abstracts the database away from the production code and will allow multiple implementations of the data store to be used with minimal issues.

In later articles, I’ll show how to use Spring to simplify these tests and the application itself. Next time, we’ll talk about the business logic and REST layers of the code.

If you have any comments, concerns, or updates I should make to this, let me know in the comments below.

Testing in Java: Part I – Introduction

As I’ve alluded to, this is the first article in a series to walk through the process of testing an application for production.  We’ll be making a simple REST interface web application that connects to a back-end database.  It will do some basic CRUD operations and I’ll show how I’d test each layer of this application.  Hopefully, you’ll find some of these techniques useful and able to apply them to your own work.  You can download, fork, or view the entire code base from the GitHub repo.

A typical web application has a few tiers: user interface, business logic, and data access.  In the case of this application I’m following the same idea, but have broken out the objects that are being modified into a domain-objects package inside of the project.  This is where we’ll start this series — talking about the objects and how to test them. I’m going to break the pure TDD-style for this series and write an object first, then write a test :).

In an application where you’re dealing with objects that the user is performing a CRUD operation upon you’ll want to think about these first.  The initial design would consist of determining what each of these objects are and create an interface and class embodying those concepts.  In our case we have a simple item that consists of a name and a unique identifier.  I’ve named it: MyItem.  Below, you’ll see the interface for MyItem along with a simple default implementation, MyItemImpl.

package com.laneholloway.unittestingexample.domain;

import java.util.UUID;

public interface MyItem {
    public UUID getGuid();
    public String getName();
}
package com.laneholloway.unittestingexample.domain;

import java.util.UUID;

/**
 * A simple default implementation
 */
public class MyItemImpl implements MyItem {
    private final UUID uuid;
    private final String name;

    public MyItemImpl(String itemName) {
        this(UUID.randomUUID(), itemName);
    }

    public MyItemImpl(UUID guid, String itemName) {
        this.uuid = guid;
        this.name = itemName;
    }

    @Override
    public UUID getGuid() {
        return uuid;
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public boolean equals(Object o) {
        if (o == null) return false;
        if (o instanceof MyItemImpl) {
            MyItemImpl that = (MyItemImpl) o;
            if (that.getGuid().equals(this.uuid) && that.getName().equals(this.name)) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
}

Now that we have the default implementation, we need to have a test for how we want the item to behave within the system. In our case, if the id and the name are the same, the objects are equal. If either is not equal, the objects are not equal. To verify this, we can write a test class using JUnit4. Looking at the code, you’ll notice that I’ve written two of the three tests and I’ve left the last one as an exercise (it really isn’t that hard :)).

package com.laneholloway.unittestingexample.domain;

import com.laneholloway.unittestingexample.domain.MyItem;
import com.laneholloway.unittestingexample.domain.MyItemImpl;
import org.junit.Before;
import org.junit.Test;

import java.util.UUID;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

/**
 * Simple tests to show off the MyItemImpl
 */
public class MyItemImplTest {
    private MyItem myItemOne;
    private MyItem myItemTwo;
    private MyItem myItemThree;

    @Before
    public void setup() throws Exception {
        UUID testId = UUID.randomUUID();
        myItemOne = new MyItemImpl(testId, "test");
        myItemTwo = new MyItemImpl(testId, "test");
        myItemThree = new MyItemImpl(UUID.randomUUID(), "test");
    }

    @Test
    public void if_uuid_and_name_are_the_same_items_are_the_same() throws Exception {
        assertTrue(myItemOne.equals(myItemTwo));
    }

    @Test
    public void if_uuids_are_different_the_items_are_different() throws Exception {
        assertFalse(myItemOne.equals(myItemThree));
    }
}

Now, pat yourself on the back, with these three classes you’ve created the object that is being modified by the program and tested it to make sure the implementation behaves as expected.

From here, we will examine the more complicated data access layer, then the business logic, and finally, the REST layer.

As always, if you have any comments, concerns, edits that I should make, let me know in the comments below.

Mocks, Fakes, and Stubs. What are they and when do I use them?

I know there has been tons of things already written about mock, fakes, and stubs available all over the Internet, but I’ve decided to add to that glut and give my spin on these wonderful testing ideas.  The first questions are: why should I care what the difference between the three is and how do I use them?  Well, I’m glad you asked those questions because, it’s really quite simple.  You use mocks, fakes, and stubs during unit testing such that you can test a small section of code in a safe manner without requiring the entire system to be instantiated to run the test.  Depending on how and what you are going to test determines which of the three methodologies you’ll use.

Now, this is all well and good, but let’s define the three methodologies.  I tend to feel Martin Fowler gives the definitions that I agree with the most, so I’ll use those:

Mock objects pre-programmed with expectations which form a specification of the calls they are expected to receive.

Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production.

Stub objects provide canned answers to calls made during the test, usually not responding at all to anything outside what’s programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it ‘sent’, or maybe only how many messages it ‘sent’.

I have a large preference for using fakes and stubs.  I’m not a huge fan of mocks since sometimes the coding gymnastics you do to get the mock behaving like you want, writing a fake could be written.  Also, mocks point to the fact, that you probably should have written an interface and implemented that instead of a single concrete implementation.  However, since I’m talking about all three of them, here are some examples on how I use each of them (and I can start with my least favorite one to get it out of the way).

Mock objects are best used when the the code being tested uses a library not under your control and you need to test very specific actions on the library.  For instance, you’ve written a wrapper to a database connector and you want to test to make sure that data read from the database is converted correctly.  In this case, I’d use a mock library (like Mockito in Java) to mock the calls to the database for the test harness.

Fakes, which are my favorite testing helper, can take the most work to get running, but they are far more flexible in my opinion once they are completed.  As described before, a fake is a working implementation of an interface that takes shortcuts in it’s implementation such that it behaves as the full implementation acts but without the overhead.  I find them most useful when testing database interactions with higher level code.  A good example of this is business logic in a server.  There is no reason to instantiate all the database layers in order to test the business logic.  It’s much easier to provide a fake implementation of the interface to the database and let the business logic do it’s thing.  In addition, these fake implementation can be used throughout your codebase anytime a database connection is needed.

Finally, there are stub objects.  Stub objects are meant to be used when only a small piece of functionality is used from a collaborating class within the codebase.  For instance, if there is a larger class being used, but only two simple methods are being used — a stub is more than likely a great choice.  Stub objects are often implemented as private inner classes to the test class such that all relevant code is kept close.    This old Spring Source blog article does a pretty good job of describing the difference between Mocks and Stubs.

In conclusion, these are three basic unit testing techniques and a quick overview of when to use each of them.  Personally, I find fakes to be the most helpful and reusable and mocks to be the least effective; however, different strokes for different folks (and codebases).  The bottom line is pick the best approach for the codebase and job at hand and test that code!