我正在为控制器方法实现一个测试用例。控制器方法如下所示,
public class LoginController{
public String register(String token){
//some logic
loginService.delete(String token);
//some logic
return "xxxx";
}
}
我正在实现测试用例来测试寄存器方法,我不希望评估方法delete。 (delete方法是返回void的服务方法)。我做了一些研究,并在我的测试方法中使用下面的代码来不评估delete方法,但是当我调试它时仍然在delete方法中。任何人都可以指出我做错了什么。
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
}
}
答案 0 :(得分:1)
将LoginController
重构为
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);
}
然后在你的测试中
public class LoginControllerTest {
private LoginController loginController;
@Test
public void testRegister(){
loginController = new LoginController(t -> {});
loginController.register("foo");
//do some assertion
}
}
我知道这不是你(可能)预期的那种解决方案,但它解决了你的问题(真正的delete
不再被调用了。)
此解决方案的其他优点:
答案 1 :(得分:0)
spy
的全部概念是,它允许您在实际实例上调用和验证方法。因此,如果你调用一个间谍实例方法,它实际上会在实际实例上调用该方法,除非它被模拟。
对于您的情况,您需要使用mock
代替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());
}
}
答案 2 :(得分:0)
只要将loginService spy
对象注入您正在测试的LoginController
,您所做的就应该正常工作。从您发布的代码中看不到这一点。
有两个原因会让控制器调用真正的登录服务方法:
您忘记将间谍注入控制器:loginControllerToTest = new LoginController(spy)
或loginControllerToTest.setLoginService(spy)
。
loginService.delete()
是一种静态方法,在这种情况下,您需要重构代码以删除静态依赖项或使用其他模拟工具(如powermock)。有关详细信息,请参阅this question。