Reputation: 121
My mockito method is hitting the real method rather than invoking the mocked method. Your inputs will be helpful
Java code.
public class CheckUser {
private final UserDao userDao;
public CheckUser (final String domain){
userDao = new UserDao(domain);
}
public IUser getExistingUser(){
if (userDao == null) {
throw new RuntimeException("userDao is null");
}
IUser existingUser = userDao.getExistingUser();
if (existingUser == null) {
throw new RuntimeException("ExistingUser is null");
}
return existingUser;
}
}
This is my JUnit test code.
@Test
public void testExistingUser() {
UserDao mockUserDao = mock(UserDao.class);
when(mockUserDao.getExistingUser()).thenReturn(getExistingTestUser());
}
private UserDao getExistingTestUser(() {
return ExistingUserImpl.Builder(). //withfield methods. build();
}
I am creating this mock object for only testing purpose. This just return the mocked MockedExistingUserImpl object which is implemented by IUser.
public class MockedExistingUserImpl implements IUser {
//fields
//overriding getter methods for all fields
//Builder for ExistingUserImpl
}
When ever I call userDao.getExistingUser() in my code, I am expecting to return the mocked Existing user object but it is hitting the real method and failing the test due to domain connection. We don't establish a domain connection to run Junits. Any inputs are appreciated. Thank you !
Upvotes: 2
Views: 2238
Reputation: 2516
Your mistake is in broken 'Dependency injection' principle.
Don't use new
operator - create UserDao at the level above and use injection.
public class CheckUser {
private final UserDao userDao;
public CheckUser (final UserDao usedDao) {
this.userDao = userDao;
}
public IUser getExistingUser() {
if (userDao == null) {
throw new RuntimeException("userDao is null");
}
IUser existingUser = userDao.getExistingUser();
if (existingUser == null) {
throw new RuntimeException("ExistingUser is null");
}
return existingUser;
}
}
Now you can test your code in the following way:
@Test
public void testExistingUser() {
UserDao mockUserDao = mock(UserDao.class);
when(mockUserDao.getExistingUser()).thenReturn(getExistingTestUser());
CheckUser checkUser = new CheckUser(mockUserDao);
IUser iUser = checkUser.getExistingUser();
// assertions here
}
private UserDao getExistingTestUser(() {
return ExistingUserImpl.Builder(). //withfield methods. build();
}
Upvotes: 2
Reputation: 140623
The answer is to read a tutorial about Mockito and follow that. You make the typical mistake: you create a mock object, but then you don't do anything so that your production code uses that mocked object.
Just doing a mock(YourClass) doesn't magically change that new() in your production code to return a mocked instance.
You need to inject that mocked instance into the code under test. For example by using the @InjectMock annotation.
For a good intro, see https://www.baeldung.com/Mockito-annotations for example.
And note: as written right now, you will have a hard time to use Mockito for your tests. Due to the direct call to new(), you would need PowerMock(ito) to test it. So: learn how to use Mockito, and then rework your production code to be easily testable. (turning to PowerMock would be the wrong strategy).
Upvotes: 3