我能夠通過在正常的servlet上下文之外實例化對象來完成Spring MVC控制器上幾乎所有的單元測試。但我希望能夠運行一些測試以確保我的對象序列化工作正常,標題正在生成等。@ExceptionHandler不能使用Spring MVC 3.1單元測試
要在servlet上下文中運行測試,我創建了一個修改的上下文文件,以便各種bean不會被構建,然後使用EasyMock在我的測試用例中創建這些bean的模擬版本。然後我用這樣的代碼調用我的處理程序,並從MockHttpServletResponse中獲得大部分所需的內容。
我覺得這得到它的本質:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "file:root-context.xml",
"file:junit-servlet-context.xml" })
public class HomeControllerConfigHandlerHttp {
@Autowired
private RequestMappingHandlerAdapter handlerAdapter;
@Autowired
private RequestMappingHandlerMapping handlerMapping;
... //miscellaneous setup
public void someTest() throws Exception
{
MockHttpServletRequest request = new MockHttpServletRequest();
request.setMethod("GET");
request.setRequestURI("/config");
request.addParameter("foo", "bar");
request.addParameter("device", "oakmont");
MockHttpServletResponse response = new MockHttpServletResponse();
Object handler = handlerMapping.getHandler(request).getHandler();
replay(dblient);
expect(serviceClient.checkDevice("oakmont")).andReturn(true);
serviceClient.destroy();
replay(serviceClient);
ModelAndView modelAndView = handlerAdapter.handle(request, response, handler);
String content = new String(response.getContentAsByteArray());
Assert.assertEquals(content, "Expected configuration");
String content_type = response.getHeader("Content-type");
Assert.assertEquals(content_type, "text/plain");
int status = response.getStatus();
Assert.assertEquals(status, 200);
這做什麼,我希望它做的事,但有一個陷阱。我使用@ExceptionHandler在控制器中執行了很多錯誤處理。這是在任何處理程序中退出錯誤情況的簡單方法,它爲我提供了暴露錯誤的一致方式。
@ExceptionHandler在正常的servlet部署中工作正常,但在本單元測試模型中,當我拋出異常時,它不會被調用。進入Spring代碼對我來說是一個挑戰,我是新手,所以我很快就迷路了。但是,它看起來像在普通的servlet環境中,有一個異常處理程序查找帶註釋的處理程序。在SpringJUnit4ClassRunner下運行時,異常處理方式不同。
如果有辦法解決這個問題,我想這樣做。由於缺乏開拓精神,我避免了spring-test-mvc,但如果有人告訴我它可以管理這個就好,我會嘗試。
我的junit-servlet-context.xml文件的內容幾乎與Spring Template MVC嚮導創建的servlet-context.xml文件相同。唯一的區別是添加了一個排除過濾器,該過濾器用於防止創建由控制器使用的幾個單例的@Component的實例化。
<?xml version="1.0" encoding="UTF-8"?>
<beans:beans xmlns="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
<!-- Enables the Spring MVC @Controller programming model -->
<annotation-driven />
<!-- Handles HTTP GET requests for /resources/** by efficiently serving up static resources in the ${webappRoot}/resources directory -->
<resources mapping="/resources/**" location="/resources/" />
<!-- Resolves views selected for rendering by @Controllers to .jsp resources in the /WEB-INF/views directory -->
<beans:bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<beans:property name="prefix" value="/WEB-INF/views/" />
<beans:property name="suffix" value=".jsp" />
</beans:bean>
<context:component-scan base-package="com.cisco.onplus.home.dmz" >
<context:exclude-filter type="regex" expression=".*InitDatabase.*"/>
</context:component-scan>
</beans:beans>
能否請您顯示您的junit-servlet-context.xml文件的內容,以及它與普通Web上下文文件的內容有何不同 – 2012-07-25 12:24:20
junit-servlet-context.xml文件與servlet-context相同.xml文件由Spring Template MVC嚮導創建,只有一個例外:添加了一個排除過濾器,該過濾器阻止初始化控制器使用的某些bean的@Component的實例化。我已將它添加到主帖子中。 – Mark 2012-07-25 13:31:41