测试 spring mvc rest 控制器

Testing a spring mvc rest controller

我正在尝试使用 MockMvcBuilders.standaloneSetup 方法为 spring mvc rest 控制器创建一个非常基本的单元测试。我不断收到 404 错误。下面我列出了我的测试应用程序上下文、我的测试 class、我的控制器和完整的堆栈跟踪。任何指导表示赞赏。

@Configuration
public class TestContext
{
    @Bean
    public Service service()
    {
        return mock(Service.class);
    }
}

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={TestContext.class})
@WebAppConfiguration
public class TestUsingWebAppContextSetUp
{
    private MockMvc mockMvc;

    @Autowired
    private Service service;

    @Before
    public void setUp()
    {
        mockMvc = MockMvcBuilders.standaloneSetup(MyController.class)
                .build();
    }

    @Test
    public void test() throws Exception
    {
        mockMvc.perform(get("/search?phoneNumber=5551112222"))
            .andExpect(status().isOk())
            .andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE));
    }
}

public class MyController
{
    @Autowired
    private Service service;

    @RequestMapping("/search")
    public List<SearchResult> search(@RequestParam(value="phoneNumber") String phoneNumber)
    {
        System.out.println("search called");
        Search search = new Search();
        search.setPhoneNumber(phoneNumber);
        return service.search(search);
    }
}

java.lang.AssertionError: Status expected:<200> but was:<404> at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60) at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89) at org.springframework.test.web.servlet.result.StatusResultMatchers.match(StatusResultMatchers.java:653) at org.springframework.test.web.servlet.MockMvc.andExpect(MockMvc.java:152) at com.mycompany.TestUsingWebAppContextSetUp.test(TestUsingWebAppContextSetUp.java:41) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 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:73) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:217) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83) at org.junit.runners.ParentRunner.run(ParentRunner.java:290) at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access[=12=]0(ParentRunner.java:58) at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

MockMvcBuilders.standaloneSetup 的 javadoc 指出

Build a MockMvc by registering one or more @Controller's instances and configuring Spring MVC infrastructure programmatically. This allows full control over the instantiation and initialization of controllers, and their dependencies, similar to plain unit tests while also making it possible to test one controller at a time.

因此您可以将其用作

mockMvc = MockMvcBuilders.standaloneSetup(new MyController()).build();

正在注册一个实际实例。如果你需要它成为一个 Spring 托管实例(你可能会考虑它有一个 @Autowired 字段),你必须从 ApplicationContext.