1

I'm trying to run integration tests for my Spring project, it's a simple get method that returns a String output from the DB for the id given. But I keep getting a NullPointerException on the Mockmvc in the MockMvc.perform within my tests.

Here is the test:

@WebMvcTest(OutputController.class)
public class OutputControllerTests {

    @Autowired
    private MockMvc mockMvc;

    @MockBea
    OutputService outputService;

    @Test
    public void returnOutputForValidId() throws Exception {
        OutputService service = Mockito.mock(OutputService.class);
        when(service.findOutputById("TEST")).thenReturn("Test output");

        String getOutputMapping = "/output/{systemID}";
        String id = "TEST";

        mockMvc.perform(get(getOuputMapping, id))
                .andDo(print()).andExpect(status().isOk())
                .andExpect(content().string("Test output"));
    }

Here is the controller - OutputController:

@RestController
public class OutputController {

    private final OutputService outputService;

    public OutputController(OutputService outputService) {
        this.outputService = outputService;
    }


    @GetMapping("/output/{id}")
    @CrossOrigin
    public String getOutputByID(@PathVariable String Id) {


        String output = outputService.findOutputById(Id);

        return output;
    }
}

The full error is :

java.lang.NullPointerException
    at .com.output.OutputControllerTests.returnOutputForValidId(OutputControllerTests.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
Gary Russell
  • 166,535
  • 14
  • 146
  • 179
ejh97
  • 25
  • 1
  • 4
  • What is line 37. Ditch `OutputService service = Mockito.mock(OutputService.class);` use the `@MockBean` mocked service instead of recreating one. If you are using JUnit 4 add `@RunWIth(SpringRunner.class)` to the class as well. – M. Deinum Aug 23 '21 at 12:27
  • Line 37 is: mockMvc.perform(get(getOuputMapping, id)) when debugging the NullPointException is on mockMvc – ejh97 Aug 23 '21 at 12:43
  • Please read the remainder of the comment, instead of only the first line. – M. Deinum Aug 23 '21 at 12:44
  • I had the NullPointerException again on the same line when using `@RunWith(SpringRunning.class)` – ejh97 Aug 23 '21 at 12:49
  • Add `@AutoconfigureMockMvc` to the class as well, also make sure you aren't mixing JUnit4 and JUnit5 as that can be painful. – M. Deinum Aug 23 '21 at 12:50
  • Have you tried with MockMvcBuilders as per my answer? It seems that mockMvc is still null... – mate00 Aug 23 '21 at 12:59
  • I've just double-checked and am just using JUnit5 now, so I have swapped the `@RunWith(SpringRunning.class)` to `ExtendWith(SpringRunning.class)` and still got the same exception in the same place – ejh97 Aug 23 '21 at 13:11
  • If you are using JUnit5 (which it doesn' t look like from your stacktrace btw) you don't need the `@ExtendWith` as the `@WebMvcTest` includes that. As stated have you added `@AutoConfigureMockMvc`? Although that should be done automatically afaik. – M. Deinum Aug 24 '21 at 05:14

1 Answers1

0

You don't need to autowire MockMvc object. Try with this instead:

import org.junit.jupiter.api.BeforeEach;
//...
private MockMvc mockMvc;
//...

@BeforeEach
public void setUp(WebApplicationContext context) {
   mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
}

mate00
  • 2,727
  • 5
  • 26
  • 34
  • 1
    With Spring Boot it automatically will do the setup and you don't neet to do it manually. – M. Deinum Aug 23 '21 at 12:25
  • At first, I was still getting the nullPointerException with this! But I have now tried this alongside some of the other commented changes and it worked! Thankyou :) – ejh97 Aug 23 '21 at 13:14
  • 1
    If you are using Spring Boot you shouldn't be using this it can actually break parts of the `@WebMvcTest` if you combine them. – M. Deinum Aug 24 '21 at 05:14