Reputation: 4701
User getUser(int id) {
User user = service.get( id );
if( user != null ) {
user.Stuff = getUserStuff( id );
return User;
}
throw new NotFoundException();
}
Stuff getUserStuff( int id ) {
stuffGetter.getStuff( id ); // stuff getter makes a rest call
return Stuff;
}
Using EasyMock, how would i test the getUser(id)
method. The confusing part for me is that getUserStuff(id)
makes an external call which I dont want to make when testing getUser
.
Upvotes: 7
Views: 18930
Reputation: 2766
As mentioned by other users in the comments, you need to provide mock instances of the objects that are making the calls that you wish to mock out.
So within getUser(id)
I can see a call to an object called service
which should be mocked out. So use a mock instance of the service class and then the call to get(id)
can be mocked out.
Then within the getUserstuff(id)
method, it uses a stuffGetter
object which could be mocked out again. Then the method being called could have expectations set up for it.
(An alternative to this could also be to set up a partial mock and mock the getUSerstuff(id)
method all together, but this is a bit beyond what you're looking to do I think)
With those things in mind, I created the following class to test your described use case:
public class ClassToTest {
private final Service service;
private final StuffGetter stuffGetter;
public ClassToTest() {
this( new Service(), new StuffGetter() );
}
public ClassToTest(final Service service, final StuffGetter stuffGetter) {
this.service = service;
this.stuffGetter = stuffGetter;
}
public User getUser(final int id) {
final User user = this.service.get( id );
if( user != null ) {
user.stuff = getUserStuff( id );
return user;
}
throw new NotFoundException();
}
public Stuff getUserStuff( final int id ) {
return this.stuffGetter.getStuff( id );
}
}
Having the constructors set up like this gives me the ability to set up mock instances of the dependencies within the tests. So what follows is a test for the getUser(id)
method that uses mocks for the two objects. It uses the basic EasyMock concepts of expect, replay and verify.
service
and the stuffGetter
. expect
method. This is where you specify what will be returned if the method you are mocking is not a void method. The tests looks like this:
import static org.junit.Assert.assertEquals;
import org.easymock.EasyMock;
import org.junit.Test;
public class ClassToTestTest {
@Test
public void thatGetIdCallsExpectedMockMethods() {
final User user = new User();
final Stuff userStuff = new Stuff();
final Service mockService = EasyMock.createMock(Service.class);
final StuffGetter mockStuffGetter = EasyMock.createMock(StuffGetter.class);
EasyMock.expect( mockService.get(15) ).andReturn( user );
EasyMock.expect( mockStuffGetter.getStuff(15) ).andReturn( userStuff );
EasyMock.replay( mockService, mockStuffGetter );
final ClassToTest classToTest = new ClassToTest( mockService, mockStuffGetter );
final User returnedUser = classToTest.getUser(15);
assertEquals(returnedUser, user);
assertEquals(returnedUser.stuff, userStuff);
EasyMock.verify( mockService, mockStuffGetter );
}
}
Upvotes: 8