Reputation: 1649
I am implementing a test case for a controller method. The controller method looks like below,
public class LoginController{
public String register(String token){
//some logic
loginService.delete(String token);
//some logic
return "xxxx";
}
}
I am implementing the test case to test the register method and i do not want the method delete to be evaluated. (The delete method is a service method that returns a void). I did a bit of research and used the below code in my test method to not evaluate the delete method, but still when i debug it goes inside the delete method. Can anyone point put me out what wrong I have done.
public class LoginControllerTest{
private loginService loginServiceMock;
@Test
public void testRegister(){
loginServiceMock = new loginServiceImpl();
loginService spy = spy(loginServiceMock);
doNothing().when(spy).delete(any(String.class));
//calling the controller method
}
}
Upvotes: 2
Views: 2877
Reputation: 11017
Whole idea of spy
is, it allows you to invoke and verify methods on actual instances. So if you invoke a spied instance method it actually invokes the method on actual instance unless it is mocked.
For your case you need to use mock
instead of spy
:
@RunWith(MockitoJUnitRunner.class)
public class LoginControllerTest{
@InjectMocks
private LoginController controller;
@Mock
private loginService loginServiceMock;
@Test
public void testRegister(){
doNothing().when(loginServiceMock).delete(anyString()));
//calling the controller method
String value = controller.register("mytoken");
verify(loginServiceMock,times(1)).delete(anyString());
}
}
Upvotes: 0
Reputation: 3370
What you are doing should work as long as loginService spy
object is injected into LoginController
that you are testing. This is not visible from the code you've posted.
There are 2 reasons that would make the controller call the real login service method :
You forgot to inject the spy into the controller: something like loginControllerToTest = new LoginController(spy)
or loginControllerToTest.setLoginService(spy)
.
loginService.delete()
is a static method in which case you need to either refactor your code to remove static dependency or use a different mocking tool such as powermock. See this question for details.
Upvotes: 0
Reputation: 4091
Refactor LoginController
to something like
public class LoginController {
private LoginService loginService;
public LoginController(LoginService loginService) {
this.loginService = loginService;
}
public String register(String token){
//some logic
loginService.delete(token);
//some logic
return "xxxx";
}
}
public interface LoginService {
void delete(String token);
}
And then in your test
public class LoginControllerTest {
private LoginController loginController;
@Test
public void testRegister(){
loginController = new LoginController(t -> {});
loginController.register("foo");
//do some assertion
}
}
I know that's not the kind of solution you (maybe) would have expected but it solves your problem (the real delete
is not called anymore).
Other advantages with this solution:
Upvotes: 1