因此,我使用带有JPA和Spring MVC的Spring Data编写此Web应用程序,我想进行模拟控制器测试。我弄清楚了如何测试GET方法,但是在我的控制器帖子方法中,新的JPA实体正在持续或使用我的服务更新。这是我的控制器的样子:
@Controller
@RequestMapping("/registerMember")
public class RegisterMemberController {
@Autowired
private MemberService memberService;
@GetMapping
public String index(RegisterMemberBean registerMemberBean) {
return "registerMember";
}
@PostMapping
public String handleSubmit(@Valid RegisterMemberBean registerMemberBean, BindingResult bindingResult, Model model) {
Member member = registerMemberBean.getMember();
boolean isRepeatPasswordCorrect = !isRepeatPasswordIncorrect(member.getPassword(), registerMemberBean.getComparePassword());
if(isAnyErrors(isRepeatPasswordCorrect, !bindingResult.hasErrors())) {
if(!isRepeatPasswordCorrect) {
model.addAttribute("isRepeatPasswordIncorrect", true).
addAttribute("isRepeatPasswordIncorrectMsg", "Passwords don't match");
}
return "registerMember";
}
boolean errUsername = !memberService.isNoOtherEntityWithUserName(0, member.getUserName());
boolean errEmail = !memberService.isNoOtherEntityWithEmail(0, member.getEmail());
if(errUsername || errEmail) {
if(errUsername) {
model.addAttribute("isExistingUserName", true).addAttribute("isExistingUserNameMsg", "Already a user with that username");
} if(errEmail) {
model.addAttribute("isExistingEmail", true).addAttribute("isExistingEmailMsg", "Already a user with that email");
}
return "registerMember";
}
getMainService().save(member);
return redirectTo("index", new RedirectEntity("member", member.getId()));
}
}
现在,在我的模拟控制器测试中,我想确保我的帖子方法执行以下操作:
- 如果BindingResults有任何错误,请重新加载页面
- 我的服务坚持DB中的会员JPA实体(如果没有错误)
- 方法将我重定向到索引页
这是我(糟糕的)测试课程到目前为止的样子:
@RunWith(SpringRunner.class)
@TestPropertySource(locations="classpath:application_test.properties")
@WebAppConfiguration
public class RegisterMemberControllerTest {
private MockMvc mockMvc;
@MockBean
private MemberService memberService;
@MockBean
private RegisterMemberController controller;
@Before
public void init() {
mockMvc = MockMvcBuilders.standaloneSetup(controller).setViewResolvers(new StandaloneMvcTestViewResolver()).build();
controller.setMainService(memberService);
}
@Test
public void testIndex() throws Exception {
mockMvc.perform(get("/registerMember"))
.andExpect(status().isOk())
.andExpect(forwardedUrl("registerMember");
}
@Test
public void testHandleSubmit() throws Exception {
RegisterMemberBean registerMemberBean = new RegisterMemberBean();
registerMemberBean.setMember(TestFixture.getValidMemberWithoutReferences());
Member member = TestFixture.getValidMember();
mockMvc.perform(post(Page.REGISTER_MEMBER)).andExpect(status().isOk());
when(mockMvc.perform(post(Page.REGISTER_MEMBER)).andExpect((ResultMatcher) memberService.save(member)).andExpect(forwardedUrl("redirect:/index/member=" + member.getId() + ".html")));
}
}
对我的理解,Spring Boot使用Mockito。我有Easymock的经验,但我想尽可能多地使用春季默认值。有人可以展示如何实现这一目标吗?
我认为在什么应该和不应该嘲笑的是有些混乱。
如果我正确阅读了您的问题,您实际上正在尝试单元测试您的RegisterMemberController
。因此,您很可能不应该对该课程进行模拟,而应该实际测试该类。
我相信您将创建 MemberService
, RegisterMemberBean
和 BindingResult
类的假货/虚拟/模拟/间谍。
将是您的单位测试创建并在测试期间交给控制器的这些类,这将迫使您有兴趣证明/证明逻辑的测试。
fyi,当验证MemberService
类被调用时,您将使用模拟。其余的类可以是假人或存根。
旁注:我建议从您的handlesubmit()方法中删除模型参数,因为它似乎在任何地方都没有使用。