1

I'm trying to create a very basic unit test for a spring mvc rest controller using the MockMvcBuilders.standaloneSetup method. I keep getting a 404 error. Below I list my Test application context, my test class, and my controller and the full stack trace. Any guidance is appreciated.

@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$10.match(StatusResultMatchers.java:653) at org.springframework.test.web.servlet.MockMvc$1.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$1.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$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.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)

1 Answer 1

5

The javadoc of MockMvcBuilders.standaloneSetup states

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.

So you would use it as

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

registering an actual instance. If you need this to be a Spring managed instance (which you probably do considering it has an @Autowired field), you'd have to get it from the ApplicationContext.

Sign up to request clarification or add additional context in comments.

4 Comments

That works. I put a package visible setter on there for now so I could inject the Service. I'll try to get the context version going at some point. Thanks!
I wonder why they have a method signature that takes a class if they expect you to instantiate it? The method signature implies they instantiate it and configure it.
@JoshChappelle To be fair, the method has a parameter type of Object. Since there's no "Controller" supertype, Spring has to accept every type which can potentially be annotated with @Controller.
Ahh didn't think about that. I didn't have the code in front of me when I made that comment. Now I just have to blame myself. :-) Thanks again.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.