I'm writing a test class for testing my 'ImporterService' class. This service reads an InputStream and creates an Object from it's data. The Object, in this case a Builder class, is instantiated within the 'ImporterService' class. To test my 'ImporterService' class I need to verify the invocations on the Builder class. For this I want to use a Mocking framework, however how is it possible to create a mock instance of the 'Builder' object outside the 'ImporterService'?
The method of my 'ImporterService' class looks like:
public Builder importFrom(BufferedReader reader) throws IOException {
String someValue = readFrom(reader);
Builder builder = new Builder(); // I need to mock this Builder object...
builder.someMethod(someValue); // to see of a method is called with the expected value
}
I was thinking about moving the creation of the Builder class into a protected method which I can override on setup of the test. But this solution seems not very nice to me as the 'ImporterService' class is leaking some internal logic and makes it possible to override the method by other classes which I do not want.
Using mock objects allows developers to focus their tests on the behavior of the system under test without worrying about its dependencies. For example, testing a complex algorithm based on multiple objects being in particular states can be clearly expressed using mock objects in place of real objects.
Mocks are used to create fully mock or dummy objects. It is mainly used in large test suites. Spies are used for creating partial or half mock objects. Like mock, spies are also used in large test suites.
Mockito provides various methods to create mock objects. mock() creates mocks without bothering about the order of method calls that the mock is going to make in due course of its action.
You can set the mock object property to the value returned by the mock object method. To achieve this, specify separate behaviors for the method and the property. You can specify one behavior at a time.
If you use any dependency injection library (like Spring) you could inject mock object instead of builder to ImporterService class. Or you could replace call to constructor with call to factory and use factory, that returns mocks in test code.
Yes, you can either do as you suggested or :
Create a Factory class in which you create Builder
objects and assign it to the reader class. In your unit tests, mock this factory and force it to build a Builder
of your choice that you can check for method calls in your unit test.
Here is an example using EasyMock showing how you can achieve this:
public class Reader{
private BuilderFactory factory = new BuilderFactory(); // Use production factory by default
public Builder importFrom(BufferedReader reader) throws IOException {
String someValue = readFrom(reader);
Builder builder = factory.buildBuilder();
builder.someMethod(someValue); // to see of a method is called with the expected value
}
}
In your unit tests you do the following:
Reader classUnderTest = new Reader();
BuilderFactory fakeFactory = EasyMock.createNiceMock(BuilderFactory.class);
Builder builder = EasyMock.createMock(Builder.class);
EasyMock.expect(fakeFactory.buildBuilder()).andReturn(builder);
builder.someMethod("value here");
EasyMock.expectLastCall().once();
EasyMock.replay(fakeFactory, builder);
classUnderTest.importFrom(bufferReader);
// Very that all calls were correctly performed on the builder
EasyMock.verify(builder);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With