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
.
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 );
}
}