0
votes

The project is spring boot application. When trying to access the api from in test case as webtestclient it is throwing nullpoint exception.

The class and the Restcontroller an and the testclass as follows

This is the class

@Component
public class GetMessage {
@Async
public void fetchData( fileType Type, String requestBody) {

        switch (A) {
            case a:
                operation(requestBody);
             break;
            case b:
                 // do some Operation
            break;
            default:
             break;
         }
 }
}

Rest controller

@RestController()
@RequestMapping("api/school/student-receiver/assignment")
public class  FileReceiverRestController {

@Autowired
    private objectMapper mapper;

@PostMapping(path = "/file", consumes = "application/json")
public ResponseEntity<String> receivefile(@RequestBody String reqBody) {        

    mapper.fetchData(fileType.A ,String reqBody);

    return new ResponseEntity<>(CALL_RESP, HttpStatus.OK);
}

Test class

@AutoConfigureWebTestClient
public class E2ETest {

  @Autowired
    private WebTestClient webTestClient ;

   String ReceiverUrl="api/school/student-receiver/assignment/file"

     @Test
     pubilic void Testapi()
    {
    webTestClient  //====> facing null exception
            .post().uri(ReceiverUrl)
            //.header("Content-Type", "application/json")
            .contentType(MediaType.APPLICATION_JSON)
            .bodyValue(requestPayload)
            .accept(MediaType.APPLICATION_JSON)
            .exchange()
            // then
            .expectStatus().isEqualTo(HttpStatus.OK);
  }
   }

java.lang.NullPointerException at E2ETest.Testapi(E2ETest.java:176) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) 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.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 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.junit.runners.ParentRunner.run(ParentRunner.java:363) 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)

1
It would be better if you provide additional log of the NPE. - IgorZ
Did you miss @SpringBootTest? - rell
Could anyone please help. - Starlene
This isn't a spring based test so @Autowired is being ignored. At @SpringBootTest or use a proper slice like @WebMvcTest. Else it won't work . - M. Deinum

1 Answers

0
votes

From how I understand this issue from the Spring Boot project, using @AutoconfigureWebTestClient only works if you are testing a WebFlux application. As you are using Spring MVC (Tomcat) and just want to make use of the WebClient /WebTestClient, this might be the reason.

The Javadoc of @AutoconfigureWebTestClient also adds a hint on this:

/**
 * Annotation that can be applied to a test class to enable a {@link WebTestClient}. At
 * the moment, only WebFlux applications are supported.
 *
 * @author Stephane Nicoll
 * @since 2.0.0
 * @see WebTestClientAutoConfiguration
 */

Nevertheless, what works is to use @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) for a test. This will ensure to autoconfigure TestRestTemplate and WebTestClient in the background:

// if you are using JUnit 4 this is also needed
// @RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class WebTestClientAccessTest {

  @Autowired
  private WebTestClient webTestClient;

  @Autowired
  private TestRestTemplate testRestTemplate;

  @Test
  public void notNull() {
    assertNotNull(webTestClient);
    assertNotNull(testRestTemplate);
  }
}

This will start the whole Spring context and you can access your application from outside using the client.

If you don't want to start the embedded Tomcat and load all beans, you can take a look at @WebMvcTest to focus on testing your web-layer. For this, you'll use MockMvc and work with a mocked servlet environment. This getting started guide from Spring Boot provides a good introduction.

Further information can be found at the Spring Boot documentation.