2017-02-24 31 views
0

因此,我正在使用彈簧數據與JPA和Spring MVC使用Spring Boot編寫此Web應用程序,並且我想進行模擬控制器測試。我想出瞭如何測試get方法,但是在我的控制器post方法中,一個新的JPA實體正在被我的服務持久化或更新。以下是我的控制器看起來像:春天mvc如何測試我的服務堅持實體發佈請求

@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())); 
    } 


} 

現在在我的模擬控制器測試我想要確保我的帖子方法執行以下操作:

  1. 刷新頁面,如果BindingResults有任何錯誤
  2. 我服務堅持分貝成員JPA實體(如果沒有錯誤)
  3. 方法重定向我的索引頁

這是我的(差)測試類的樣子至今:

@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"))); 

    } 
} 

我的理解春季Boot使用的Mockito。我對EasyMock有一些經驗,但我想盡可能使用spring默認值。有人可以展示如何實現這一目標?

回答

1

我認爲在應該和不應該被嘲笑的問題上存在一些混淆。

如果我正確地閱讀你的問題,你實際上是在嘗試單元測試你的RegisterMemberController。因此,你很可能不應該對該類進行模擬,而是實際測試該類。

我相信你會創造fakes/dummies/stubs/mocks /你MemberServiceRegisterMemberBeanBindingResultspies

這些類將由您的單元測試創​​建並在測試過程中交給您的控制器,這將強制對您感興趣的邏輯進行測試/驗證。

僅供參考,在驗證MemberService類被調用時,這就是您要使用模擬的地方。其餘的課程可以是假人或存根。

邊注:我建議從您的handleSubmit()方法中刪除Model參數,因爲它似乎沒有在任何地方使用。

+0

良好的電話@hooknc周圍。我還要補充一點,在某些情況下,編寫集成測試可能實際上會將數據保存到數據庫中。當我們需要驗證這樣的場景時,我們使用maven-failsafe插件。 –

+0

@MichaelPeacock我也對我所有的Repository類進行了集成測試,因此已經處理好了。 – Johan

+0

@hooknc我實際上使用了Model參數。我上傳了post方法的簡化版本,並不想讓它變得臃腫。現在上傳完整版本。爲什麼我要測試這些步驟是因爲我想避免實時測試視圖中的邏輯,因爲它被證明非常乏味。我會檢查你發佈的有關假貨/假人/存根的鏈接。我有點不清楚什麼是什麼。 – Johan