Java 使用 MockMVC 测试 Spring MVC 路由器

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20978535/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 05:41:50  来源:igfitidea点击:

Testing Spring MVC Router with MockMVC

javaspring-mvcjunitspring-mvc-test

提问by AVP

I'm trying to test my Spring MVC webapp with Spring test. It uses springmvc-routerfor routing and that appears to break the tests, which work fine when I use @RequestMappinginstead of my routes.conffile.

我正在尝试使用 Spring 测试来测试我的 Spring MVC webapp。它使用springmvc-router进行路由,这似乎破坏了测试,当我使用@RequestMapping而不是我的routes.conf文件时,它可以正常工作。

I have a .jspfile called valid.jsp, and it displays fine when I run the development site from Jetty. The controller is:

我有一个.jsp名为的文件valid.jsp,当我从 Jetty 运行开发站点时它显示正常。控制器是:

@Controller
@EnableWebMvc
public class AuthController {
  public String valid() {
    return "valid";
  }
}

My routes.conffile maps GET /valid authController.valid.

我的routes.conf文件映射GET /valid authController.valid

Now, my tester looks like

现在,我的测试员看起来像

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"/test-context.xml",
    "/spring/spring-security.xml",
    "file:src/main/webapp/WEB-INF/mvc-config.xml"})
@WebAppConfiguration
@Import(RouteConfig.class)
public class AuthControllerTest {
  private MockMvc mockMvc;

  @Autowired
  private WebApplicationContext webApplicationContext;

  @Autowired
  private AuthenticationManager authenticationManager;

  @Before
  public void init() {
    MockitoAnnotations.initMocks(this);
    mockMvc =
        MockMvcBuilders.webAppContextSetup(webApplicationContext).dispatchOptions(true).build();
  }

  @Test
  public void testValid() throws Exception {
    mockMvc.perform(get("/validation-success"))
        .andDo(print())
        .andExpect(status().isOk());
  }

When the mockMvc.perform()is run, a NullPointerException is thrown:

mockMvc.perform()运行时,则抛出NullPointerException:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:943)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807)
    at org.springframework.test.web.servlet.TestDispatcherServlet.service(TestDispatcherServlet.java:64)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:770)
    at org.springframework.mock.web.MockFilterChain$ServletFilterProxy.doFilter(MockFilterChain.java:170)
    at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:137)
    at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:141)
    at com.mypackage.AuthControllerTest.testValid(AuthControllerTest.java:45)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
    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:232)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access
mockMvc.perform(get("/validation-success")
       .header("host", "localhost:80"))
       .andExpect(status().isOk());
0(ParentRunner.java:53) at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:229) 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:309) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:175) at org.junit.runner.JUnitCore.run(JUnitCore.java:160) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:77) at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:195) at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:63) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120) Caused by: java.lang.NullPointerException at org.resthub.web.springmvc.router.HTTPRequestAdapter.parseRequest(HTTPRequestAdapter.java:196) at org.resthub.web.springmvc.router.RouterHandlerMapping.getHandlerInternal(RouterHandlerMapping.java:166) at org.springframework.web.servlet.handler.AbstractHandlerMapping.getHandler(AbstractHandlerMapping.java:300) at org.springframework.web.servlet.DispatcherServlet.getHandler(DispatcherServlet.java:1101) at org.springframework.test.web.servlet.TestDispatcherServlet.getHandler(TestDispatcherServlet.java:104) at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:916) at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:876) at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:931) ... 41 more

So the question is: is it possible to use Spring's test framework with springmvc-router?

所以问题是:是否可以将 Spring 的测试框架与 springmvc-router 一起使用?

采纳答案by TheMasster12

After doing some digging, I've discovered that the HTTPRequestAdapter.parseRequest()method has an issue with the way that MockMVC sends requests. Specifically, the request sent by MockMVC doesn't include a header in the request with the name host.

在做了一些挖掘之后,我发现该HTTPRequestAdapter.parseRequest()方法在 MockMVC 发送请求的方式上存在问题。具体来说,MockMVC 发送的请求在请求中不包含名称为 的标头host

HTTPRequestAdapterrequires that header and does not account for the fact that it can be null, so it generates the NullPointerException.

HTTPRequestAdapter需要该标头并且不考虑它可以为空的事实,因此它生成NullPointerException.

I fixed the issue with this code:

我用这段代码解决了这个问题:

##代码##

The hostheader won't be null and your tests should pass.

host头将不为空,你的测试应该通过。