Mocking Writer.write in Java using EasyMock
I am writing this as finding the solution to the problem that I was having while mocking a Writer in Java using EasyMock took far too long. Hopefully others having the same issue will stumble across this blog post.
I have a class that takes a Writer as a constructor argument. This Writer is then used throughout the class! Code for the constructor can be seen below:
public Processor(Writer writer) throws IOException { this.writer = writer; this.writer.write("This is a list of stuff\n----\n"); }
After reading the EasyMock documentation and other pages and tutorials etc. on-line I established that mocks are created using EasyMock.createMock() and then expected method calls are added using EasyMock.expect(). (You can also use the static methods). My first attempt looked something like this:
public class ProcessorTest extends TestCase { public void testProcessor_constructWrites() throws Exception { Writer writer = EasyMock.createMock(Writer.class); EasyMock.expect(writer.write("This is a list of stuff\n----\n")); EasyMock.replay(writer); new Processor(writer); EasyMock.verify(writer); } }
This however will not build. This is due to the fact that EasyMock.expect() can not be used with void methods, of which Writer.write is one. After a little more digging into how mocking in Java even worked and a little more reading I came up with the below solution:
public class ProcessorTest extends TestCase { public void testProcessor_constructWrites() throws Exception { Writer writer = EasyMock.createMock(Writer.class); writer.write("This is a list of stuff\n----\n"); EasyMock.expectLastCall(); EasyMock.replay(writer); new Processor(writer); EasyMock.verify(writer); } }
If you call a method on a mock before EasyMock.reply() is called this will be counted as an expected method if Easymock.expectLastCall() is called after each of the expected method calls. So for expecting multiple calls on an object where the method returns void you would end up with some code that looks like this:
// Create the mock Writer writer = EasyMock.createMock(Writer.class); // Add the expected calls writer.write("Write line 1"); EasyMock.expectLastCall(); writer.write("Write line 2"); EasyMock.expectLastCall(); writer.write("Write line 3"); EasyMock.expectLastCall(); EasyMock.replay(writer); // Do stuff that uses writer to make the calls // Verify the calls EasyMock.verify(writer);
This example was created when making this commit.