在单元测试中,我需要在弹簧@Controller中模拟数据模型实例,否则@RequestMapping方法的返回值会出错。
为此,我尝试了以下操作:
这是控制器方法:
@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对象具有模拟用户类型而不是User类型,并且login()方法被调用一次(相应地)并返回“ true”。
但是我得到的只是 “想要但不被调用:mockUser.login() 实际上,与该模拟游戏的互动为零。”
我很乐意为解决我的问题提供任何建议,因为我已经花了相当长的时间从事这项工作,但我似乎还不明白。
答案 0 :(得分:0)
1):这似乎是一项IT测试。您不应强行进行任何注射。spring会这样做:
@InjectMocks
private LoginController injectedLoginController;
2):您需要监视控制器:
@SpyBean
private LoginController injectedLoginController;
3)您需要将User
的创建移至控制器内部的包级方法:
user = createUser(username, username, hashedPW.getBytes(), LoginHandler.getInstance());
...
User createUser(...){
return new User(username, username, hashedPW.getBytes(), LoginHandler.getInstance());
}
4):使该方法返回模拟的用户:
doReturn(mockUser).when(injectedLoginController).createUser(...);
when(mockUser.login()).thenReturn(true);
答案 1 :(得分:0)
如果您不想更改代码,可以从PowerMockito
寻求帮助,这可以帮助模拟新对象的构建。
@RunWith(PowerMockRunner.class)
@PrepareForTest({User.class})
public class ControllerUnderTest {
// here User is class for which we want to mock object creation
}
现在,让我们模拟对象
@Test
public void testLoginSuccess() throws Exception {
....
User userMock = PowerMockito.createMock(User.class);
PowerMockito.whenNew(User.class).withArguments(username, username, hashedPW.getBytes(), LoginHandler.getInstance()).thenReturn(userMock);
expect(userMock.login()).andReturn(true);
verify(mockUser).login();
...
}
有关powermock
的更多详细信息,请检查此PowerMockito