2012-06-30 39 views
2

我使用:如何測試Spring MVC的控制器與RedirectAttributes

  • 春3.1
  • JUnit的4.10

我試圖寫一個JUnit測試案例與RedirectAttributes控制器。

控制器的簽名是:

@RequestMapping(method = RequestMethod.POST) 
public String homePOST(@Validated({ IBasic.class }) @ModelAttribute("userCommand") User userCommand, 
      BindingResult result, Model model, 
      RedirectAttributes flashAttributes) 

JUnit測試的情況是:

@RunWith(SpringJUnit4ClassRunner.class) 
    @ContextConfiguration(locations = { "/root-context.xml", "/servlet-context.xml" }) 
public class HomeControllerTest { 

    @Autowired 
    private RequestMappingHandlerAdapter handlerAdapter; 

    @Autowired 
    private RequestMappingHandlerMapping handlerMapping; 

    @Test 
    public void testHomePOST() { 
     MockHttpServletRequest request = new MockHttpServletRequest("POST", "/"); 
     request.addParameter("username", "user1"); 
     request.addParameter("password", "mypasswd"); 

     MockHttpServletResponse response = new MockHttpServletResponse(); 

     Object handler; 

     try { 
      handler = handlerMapping.getHandler(request).getHandler(); 

      ModelAndView modelAndView = handlerAdapter.handle(request, 
        response, handler); 

      assertViewName(modelAndView, "redirect:/myview"); 
     } catch (Exception e) { 
      String err = "Error executing controller : " + e.toString(); 

      fail(err); 
     } 
    } 
} 

當執行handlerAdapter.handle(),我得到:

java.lang.AssertionError: Error executing controller : java.lang.NullPointerException 
at org.junit.Assert.fail(Assert.java:93) 
at com.myapps.service.impl.test.HomeControllerTest.testHomePOST(HomeControllerTest.java:75) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
at java.lang.reflect.Method.invoke(Method.java:597) 
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) 
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) 
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) 
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) 
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) 
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) 
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:300) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

如果我刪除來自控制器的RedirectAttributes,它工作正常。

任何人都可以請提供一些幫助如何測試與RedirectAttributes控制器?

預先感謝您。

爲了模擬這一點,這裏是控制器代碼:

@Controller 
@RequestMapping(value = "/") 
public class HomeController { 
    @RequestMapping(method = RequestMethod.POST) 
    public String homePOST(
      @Validated({ IBasic.class }) @ModelAttribute("userCommand") User userCommand, 
      BindingResult result, Model model, 
      RedirectAttributes flashAttributes) { 

     return "redirect:/myview"; 
    } 
} 
+0

什麼都沒有跳出來,你能不能粘貼根異常呢。 –

+0

我沒有收到任何其他異常。如果它有助於輕鬆地進行模擬,那麼我將使用控制器更新原始帖子。 –

回答

5

我能夠複製您的問題 - 該問題的根本原因是,如果一個RedirectAttributes存在作爲處理方法參數,那麼在從處理程序適配器返回之前,會拉出輸出「flashmap」並將flashAttributes添加到它。現在,這個輸出flashMap是從httprequest中獲取的 - 在您的情況下,您的MockHttpServletRequest爲空。

的解決方法是隻需在MockHttpServletRequest設置虛擬輸出flashMap:

request.setAttribute(DispatcherServlet.OUTPUT_FLASH_MAP_ATTRIBUTE,new FlashMap()); 

現在,這對我的作品。你能否請嘗試看看它是否爲你解決了這個問題。

+0

謝謝Biju,它工作得很好!看起來它必須被建議作爲對Spring團隊的MockHttpServletRequest的增強? –

0

使用mockito框架來模擬它。 在設置功能使用

RedirectAttributes flashAttributes; 
flashAttributes=Mockito.mock(RedirectAttributes.class) 

相關問題