【发布时间】:2019-10-17 05:40:16
【问题描述】:
在我的单元测试中,我需要在 spring @Controller 中模拟一个数据模型实例,否则 @RequestMapping 方法的返回值会出错。
为此,我尝试了以下方法:
- 创建一个User mock,调用user.login(),需要返回“true”
- 在 LoginController 中注入模拟对象
- 存根登录方法以返回 true
- 使用 Spring 测试中的 MockMVC 执行 POST /Login
- 验证是否调用了 mockUser.login
这里是控制器方法:
@RequestMapping(value = "/Login", method = RequestMethod.POST)
public String updateUI(Locale locale, Model model, @RequestParam("username") String username,
@RequestParam("hashedPW") String hashedPW, HttpServletRequest request) {
model.addAttribute("username", username);
user = new User(username, username, hashedPW.getBytes(), LoginHandler.getInstance());
boolean loginResult = user.login();
if(loginResult == true) {
return "profile";
}
String output = "Failed login (" + username + ") requested, locale = " + locale;
log(output);
return "home";
}
以及我通过注入初始化模拟对象:
@Mock
private User mockUser;
@InjectMocks
private LoginController injectedLoginController;
@Before
public void setup() throws ServletException {
MockitoAnnotations.initMocks(this);
mvc = MockMvcBuilders.standaloneSetup(injectedLoginController).build();
LOGFILE = new File("logs/general.log");
}
最后是单元测试:
@Test
public void testLoginSuccess() throws Exception {
String username = "Stefan";
byte[] hashedPW = "".getBytes();
when(mockUser.login()).thenReturn(true);
ResultActions ra = mvc
.perform(post("/Login").param("username", username).param("hashedPW", hashedPW.toString()))
.andExpect(status().isOk());
verify(mockUser).login();
}
总的来说,我希望控制器处理的 User 对象是 mockUser 类型而不是 User,并且 login() 方法会被调用一次(相应地)并返回“true”。
但我得到的只是 “需要但未调用:mockUser.login() 实际上,与此模拟的交互为零。”
感谢任何解决我的问题的建议,因为我已经为此工作了很长一段时间,但我似乎不明白这一点。
【问题讨论】:
-
如果你删除最后一行
verify(mockUser).login();,你通过了这个测试吗? -
没有调用模拟的原因是代码中的
user = new User(username, username, hashedPW.getBytes(), LoginHandler.getInstance());行。如果您看到那里,则实例化了一个新对象。因此永远不会调用来自模拟对象的方法。 -
您还没有向我们展示您将模拟用户注入控制器的位置。即使你这样做了,你也会用一个新的用户实例覆盖它
-
感谢您的帮助! @yuanqingfei:是的,没有这条线就过去了。
-
@Lesiak :如果我没看错的话,我认为注释 Mock 和 InjectMocks 会进行注入,你能确认一下吗?
标签: java spring mockito spring-test