0

I am writing junit test for my request method. Im using mockMvc to trigger the rest request. When I run my test I get the error

java.lang.NullPointerException: Cannot invoke "org.springframework.test.web.servlet.ResultActions.andExpect(org.springframework.test.web.servlet.ResultMatcher)" because the return value of "org.springframework.test.web.servlet.MockMvc.perform(org.springframework.test.web.servlet.RequestBuilder)" is null

Here is my request method definition

@RequestMapping(value = "data/upload", method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA)
@CrossOrigin
@Loggable (activityname = ActivityLogConstants.CONFIG_DATA_UPLOAD, operationName =ActivityLogConstants.UPLOAD_OPERATIONNAME)
public Response importConfigData(HttpServletRequest request, @RequestParam("file") MultipartFile inFile, @RequestParam("rowData") String rowData) throws ServiceException {
....
}

I have HttpServletRequest,Multipartfile and String arguments to this method.

Here is my test

@ExtendWith(SpringExtension.class)
public class ConfigUploadTest {
@MockBean
private MockMvc mockMvc;


@InjectMocks
private UploadController uploadController;

@Test
public void vnfmService_ConfigUploadShouldReturnStatusOkTest() throws Exception {
    MockMultipartFile file = new MockMultipartFile(
            "file", // The request parameter name
            "test.xml", // The original filename (with .xml extension)
            "application/xml", // The content type for XML
            "<?xml version=\"1.0\" encoding=\"UTF-8\"?><data>This is some XML content</data>".getBytes());
    MockMultipartHttpServletRequestBuilder request = MockMvcRequestBuilders.multipart("/data/upload");
    request.file("file", file.getBytes());
    request.param("rowData","{"test":"test"}");
    mockMvc.perform(request).andExpect(status().isOk());
}
}

I don't want to load my entire application context and hence I'm using @ExtendWith(SpringExtension.class)

Please advise.

1 Answer 1

0

There appears to be a few errors.

First, you have used @MockBean on MockMvc. @MockBean creates a mock of an existing bean within your code. You want to have the actual instance of MockMvc so you need to autowire it using the @Autowired annotation.

This won’t work alone leading to the second point, you should be using @WebMvcTest which includes @ExtendsWith(SpringExtension.class) internally. This will setup MockMvc to work for your test with your code.

Third, you are using @InjectMocks with your controller. Since you are testing the http call, this is unnecessary and can be removed.

So with these changes, it should look something like this:

@WebMvcTest(UploadController.class)
public class ConfigUploadTest {
  @Autowired
  private MockMvc mockMvc;

  @Test

You should read the Spring Boot Reference Documentation for more information about how Spring tests work.

3
  • @WebMvcTest loads the entire application context, for some reason I cannot find symbol compilation errors when i use this. Hence i don't want to load the application context but run unit test only for one class.
    – manjosh
    Commented Jun 11 at 3:46
  • @manjosh @WebMvcTest only loads the Spring MVC infrastructure and the controller you specify in the annotation. It doesn’t load the application context. If you want a pure unit test then you wouldn’t be able to use MockMvc as you can only test the class without any infrastructure. You should read the reference documentation I shared more closely as I believe it does what you are trying to accomplish. Commented Jun 11 at 9:26
  • Small correction to what I typed, it doesn’t load all your classes so your application context settings shouldn’t affect the test unless some of the settings in your application context are directly used in your controller. You may share your full controller to potentially show why you are getting other issues. Commented Jun 11 at 9:36

Not the answer you're looking for? Browse other questions tagged or ask your own question.