Java SpringMVC如何在post请求中测试我的服务是否持久化

Java SpringMVC如何在post请求中测试我的服务是否持久化,java,spring-boot,spring-data,mockito,spring-mvc-test,Java,Spring Boot,Spring Data,Mockito,Spring Mvc Test,因此,我正在使用Spring数据和JPA和Spring MVC编写这个带有Spring引导的web应用程序,我想进行模拟控制器测试。我知道了如何测试get方法,但是在我的controllers post方法中,一个新的JPA实体正在被持久化,或者被我的服务更新。以下是我的控制器的外观: @Controller @RequestMapping("/registerMember") public class RegisterMemberController { @Autowired

因此,我正在使用Spring数据和JPA和Spring MVC编写这个带有Spring引导的web应用程序,我想进行模拟控制器测试。我知道了如何测试get方法,但是在我的controllers post方法中,一个新的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()));
    }


}
现在,在模拟控制器测试中,我希望确保我的post方法执行以下操作:

  • 如果BindingResults有任何错误,请重新加载页面
  • 我的服务将成员JPA实体保存在db中(如果没有错误)
  • 方法将我重定向到索引页
  • 到目前为止,这就是我的(糟糕的)测试类的样子:

    @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有一些经验,但我希望尽可能多地使用spring默认值。有人能展示一下如何做到这一点吗?

    我认为在什么应该和不应该被嘲笑的问题上有点困惑

    如果我没有看错您的问题,您实际上是在尝试单元测试您的
    RegisterMemberController
    。因此,您很可能不应该对该类进行模拟,而应该实际测试该类

    我相信您将创建///个
    MemberService
    RegisterMemberBean
    BindingResult

    这些类将由您的单元测试创建,并在测试期间交给您的控制器,这些类将强制测试您感兴趣证明/反驳的逻辑

    仅供参考,在验证是否调用了
    MemberService
    类时,您将使用模拟。其余的类可以是傻瓜或存根


    旁注:我建议从handleSubmit()方法中删除模型参数,因为它似乎没有在任何地方使用。

    Good calls all around@hooknc。我还要补充一点,在某些情况下,可能值得编写集成测试,将数据实际持久化到数据库中。当我们需要验证这样的场景时,我们使用maven failsafe插件。@MichaelPeacock我还对我的所有存储库类进行了集成测试,因此这些测试已经完成了。@hooknc我实际上在使用模型参数。我上传了一个简化版的post方法,不想让它变得臃肿。现在已上载完整版本。我之所以要测试这些步骤,是因为我想避免在视图中对逻辑进行实时测试,因为它被证明是相当乏味的。我会查看你发布的关于假货/假人/存根的链接。我有点不清楚什么是什么。