-1

I'm writing JUnit for my REST API endpoint, I've created a simple hello world controller class and JUnit for that but I'm getting below exception while executing the JUnit test case. It would be really helpful if someone can help me to resolve this. I'm using JDK 6 with Spring 4.3 version

Note: I'm not using spring-context XML - I'm using Java annotation

HelloController.java

@RestController
@RequestMapping("/hello")
public class HelloController {

    @GetMapping
    public String helloWorld() {

        return "hello World";

    }
}

HelloControllerTest.java

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {HelloController.class})
public class HelloControllerTest {

    private MockMvc mockMvc;

    @InjectMocks
    private HelloController helloController;

    @Before
    public void setUp() throws Exception {
        mockMvc = MockMvcBuilders.standaloneSetup(helloController).build();

    }

    @Test
    public void testHelloWorld() throws Exception {

        mockMvc.perform(MockMvcRequestBuilders.get("/hello")).andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.content().string("hello World"));

    }
}

Exception:

java.lang.NullPointerException
    at org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.detectHandlerMethods(AbstractHandlerMethodMapping.java:227)
    at org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder$StaticRequestMappingHandlerMapping.registerHandlers(StandaloneMockMvcBuilder.java:486)
    at org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder.registerMvcSingletons(StandaloneMockMvcBuilder.java:352)
    at org.springframework.test.web.servlet.setup.StandaloneMockMvcBuilder.initWebAppContext(StandaloneMockMvcBuilder.java:337)
    at org.springframework.test.web.servlet.setup.AbstractMockMvcBuilder.build(AbstractMockMvcBuilder.java:139)
    at HelloControllerTest.setUp(HelloControllerTest.java:32)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:60)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:37)
    at java.lang.reflect.Method.invoke(Method.java:611)
    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.RunBefores.evaluate(RunBefores.java:24)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
    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:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
    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:538)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
learn groovy
  • 487
  • 4
  • 11
  • 28
  • 2
    Possible duplicate of [Spring not autowiring in unit tests with JUnit](https://stackoverflow.com/questions/17623694/spring-not-autowiring-in-unit-tests-with-junit) – Ervin Szilagyi Nov 29 '18 at 21:05
  • @ErvinSzilagyi I tried with ContextConfiguration but I'm getting a different error now - updated my original post – learn groovy Nov 29 '18 at 21:46

2 Answers2

0

If you're using the standaloneSetup you do not need to run it with the SpringJUnit4ClassRunner. That runner expects a Spring Configuration.

You can either init a new HelloController yourself

e.g.

public class HelloControllerTest {

    private MockMvc mockMvc;

    private HelloController helloController = new HelloController();

    @Before
    public void setUp() throws Exception {
        mockMvc = MockMvcBuilders.standaloneSetup(helloController).build();

    }

    @Test
    public void testHelloWorld() throws Exception {

        mockMvc.perform(MockMvcRequestBuilders.get("/hello")).andExpect(MockMvcResultMatchers.status().isOk())
                .andExpect(MockMvcResultMatchers.content().string("hello World"));
    }

or you can let Spring do it by injecting your WebApplicationContext and building it by using whatever Configuration is required to create the WebApplicationContext

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = MyWebApplicationConfig.class)
public class HelloControllerTest {

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    private HelloController helloController;

    @Before
    public void setUp() throws Exception {
        mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();

    }

Or Finally, if you happen to be using Spring Boot you can use one of their Slice Test annotations,

    @RunWith(SpringRunner.class)
    @WebMvcTest
    public class HelloControllerTest {

    @Autowired 
    private MockMvc mockmvc;

   }
Darren Forsythe
  • 10,712
  • 4
  • 43
  • 54
-2

I got it - in setUp() - not instantiated HelloController, after adding below line my test case passed.

helloController = new HelloController();
learn groovy
  • 487
  • 4
  • 11
  • 28