Software Construction
Mock Testing
Jürg Luthiger University of Applied Sciences Northwestern Switzerland Institute for Mobile and Distributed Systems
Learning Target
You can describe the concepts behind Mock testing can use Mock Objects as an efficient way to do Unit Testing
Institute for Mobile and Distributed Systems J. Luthiger 2 Agenda
Introduction into Mock Testing Introduction into EasyMock2
Institute for Mobile and Distributed Systems J. Luthiger 3
Unit Testing (Reminder!)
Unit Testing is done on each module in isolation to verify its behavior Unit test will establish some kind of artificial environment invoke routines in the module under test check the results against known values
Institute for Mobile and Distributed Systems J. Luthiger 4 Limits of Unit Testing
Some things can't be tested in isolation Configuration JDBC code z Testing for connection acquisition and release is not very interesting O/R mappings
... and, of course, how classes work together
Institute for Mobile and Distributed Systems J. Luthiger 5
Test Double in Unit Testing
Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists. Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in-memory database is a good example). Stubs 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'. Mocks objects pre-programmed with expectations which form a specification of the calls they are expected to receive.
Institute for Mobile and Distributed Systems J. Luthiger 6 Testing with Stubs
Stub is a dumb object! A Stub is just an object that returns the same value over and over. For example:
String Stub.getMethod() { return "test";}
Institute for Mobile and Distributed Systems J. Luthiger 7
Exercise: Testing with Stub Objects
public class JukeBoxTestTemplate { private static String songTitle = "Coldplay - Talk"; private JukeBox jukeBox; private Song stubSong;
@Before Use a Stub Object! public void setUp() throws Exception { } How is it look like?
@Test(expected = JukeBoxException.class) public void testPlayOfNonexistingSong() { }
@Test public void testGetPlayList() { }
@Test public void testPlay() { }
@Test(expected = JukeBoxException.class) public void testPlayOfAlreadyPlayingSong() { } }
Institute for Mobile and Distributed Systems J. Luthiger 8 Testing with Mocks
A Mock is intelligent It can test itself. You can use and verify it to check if its state is valid. For example:
mock.verify()
Institute for Mobile and Distributed Systems J. Luthiger 9
Mock Testing
Mock objects simulate parts of the behavior of domain objects. Domain classes can be tested in isolation by simulating their collaborators with Mock Objects. Takes classes out of a natural environment and puts them in the lab.
Institute for Mobile and Distributed Systems J. Luthiger 10 When to use Mock objects
The real object has non-deterministic behavior. The real object is difficult to set up. The real object is slow. The real object has a user interface. The test needs to ask the real object about how it was used (-> callback function was used) The real object does not yet exist. from "Pragmatic Unit Testing"
Institute for Mobile and Distributed Systems J. Luthiger 11
Pros and cons of Mock Objects
Pros Enforce the message that testing is about isolation Can simplify working with interfaces with many methods Can enable near-instant testing even of code that uses resource-bound APIs such as JDBC Cons Can mirror the implementation too closely, making the test suite fragile Mocking can become complex with APIs like JDBC
Institute for Mobile and Distributed Systems J. Luthiger 12 EasyMock 2
Writing and maintaining Mock Objects often is a tedious task that may introduce errors. EasyMock 2 is a library that provides an easy way to use Mock Objects for given interfaces. EasyMock 2 generates Mock Objects dynamically - no need to write them, and no generated code http://easymock.org
Institute for Mobile and Distributed Systems J. Luthiger 13
EasyMock 2 benefits
Hand-writing classes for Mock Objects is not needed. Supports refactoring-safe Mock Objects: test code will not break at runtime when renaming methods or reordering method parameters Supports return values and exceptions. Supports checking the order of method calls, for one or more Mock Objects.
Institute for Mobile and Distributed Systems J. Luthiger 14 EasyMock drawbacks
EasyMock 2.3 does only work with Java 2 Version 5.0 and above. EasyMock by default supports the generation of Mock Objects for interfaces only. For those who would like to generate Mock Objects for classes, there is an extension available at the EasyMock home page.
see "EasyMock 2.3 Class Extension"
Institute for Mobile and Distributed Systems J. Luthiger 15
Usage Pattern
Create a Mock Object for the interface we would like to simulate Record the expected behavior Switch the Mock Object to replay state Do the normal testing Verify behavior
Institute for Mobile and Distributed Systems J. Luthiger 16 Create Mock
Use method createMock(
import static org.easymock.EasyMock.createMock;
/* * create a mock */ Song mock = createMock(Song.class);
Institute for Mobile and Distributed Systems J. Luthiger 17
Record Method Calls
In the record state, the Mock Object does not behave like a Mock Object, it records method calls expected to be called during the tests.
//record all method calls to the mock object mock.start();
// wrap call with expect() method to specify return value expect(mock.getTitle()).andReturn("My Song Title");
Institute for Mobile and Distributed Systems J. Luthiger 18 Switch to Replay Mode and Test
After calling replay, the Mock Object checks whether the expected method calls are really done.
/* * switch to replay mode */ replay(mock);
/* * run the actual tests */ …
Institute for Mobile and Distributed Systems J. Luthiger 19
Verify behavior
If we specify behavior, we would like to verify that it is actually used. To verify that the specified behavior has been used, we have to call verify(mock)
/* * verfiy behavior */ verify(mock);
Institute for Mobile and Distributed Systems J. Luthiger 20 Example: JukeBox
Isolation «Schnittstelle» «Schnittstelle» JukeBox 1* Song +addSong() +getTitle() +playTitle() +getPlayTime() +getPlayList() +isPlaying() +getActualSong() +start()
MusicJukeBox
Class under Test
Institute for Mobile and Distributed Systems J. Luthiger 21
Using EasyMock
To remember: expectation setting stage vs. replay stage createMock() vs. createStrictMock() wrapped vs. unwrapped behavior calls on the mock object for which no expectation has been set vs. recorded expectations for calls which are not made using expectLastCall() to express multiple method calls vs. throwing an exception
Institute for Mobile and Distributed Systems J. Luthiger 22 Ressources
EasyMock http://www.easymock.org
Paper "Mocks Aren't Stubs" http://www.martinfowler.com/articles/mocksArentStubs.html
EasyMock Tutorial http://www.realsolve.co.uk/site/tech/easymock.php
Kapitel 11: Der Einsatz von Mock-Objekten mit EasyMock
Institute for Mobile and Distributed Systems J. Luthiger 23