Georgi Michev
Georgi Michev

Reputation: 894

Test endpoint with HTTP GET

I would like to test the endpoint if the response and HTTP code are correct. The controller method looks like this:

@CrossOrigin
@RequestMapping(method = RequestMethod.GET, value = "/{ruleId}")
public Rule loadOneRule(@PathVariable String ruleId) {
    return rulesService.loadOneRule(ruleId);
}

The test method is

@Test
public void loadOneRule() throws IOException, URISyntaxException { 
    NodeDTO nodeDto = new NodeDTO();
    HashMap<String, NodeDTO> nodes = new HashMap<>();
    nodes.put("foo", nodeDto);

    Rule rule = new Rule("my rule", nodes);
    RuleService ruleService = new RuleService();
    rule = ruleService.saveRule(rule);
    String id = rule.getId().toString();

    String target = "http://localhost:8090" + "/v2/rules/" + id; 

    URI uri = new URI(target);
    HttpGet httpGet = new HttpGet(uri.toASCIIString());

    HttpResponse response = httpClient.execute(httpGet);
    int HTTPcode = response.getStatusLine().getStatusCode();
    HttpEntity entity = response.getEntity();
    String json = EntityUtils.toString(entity);

    ObjectMapper objectMapper = new ObjectMapper();
    Rule targetRule = objectMapper.readValue(json, Rule.class);

    boolean correctStatus = HTTPcode >= 200 && HTTPcode <= 300 ? true : false;
    boolean correctResponse = targetRule != null ? true : false;

    assertTrue(correctStatus);
    assertTrue(correctResponse);

}

I get nullpointer exception on my ruleService. It is the same even if I try to @Autowire it and not instantiate it. I guess the whole approach about getting one rule object from the mongo database is wrong, but putting an object locally in my database and getting this object by his id would be even worse, since these tests will not run on my computer.

This is the exception if I try to autowire my service

java.lang.NullPointerException
at com.%%%%.^^^^.controller.v2.test.RuleControllerTest.loadOneRule(RuleControllerTest.java:96)
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.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 org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:42)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(Unknown Source)
at java.util.Iterator.forEachRemaining(Unknown Source)
at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Unknown Source)
at java.util.stream.AbstractPipeline.copyInto(Unknown Source)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(Unknown Source)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(Unknown Source)
at java.util.stream.AbstractPipeline.evaluate(Unknown Source)
at java.util.stream.ReferencePipeline.forEach(Unknown Source)
at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:83)
at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:74)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.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)

Upvotes: 0

Views: 462

Answers (1)

Gaurav Srivastav
Gaurav Srivastav

Reputation: 2551

You don't need make request using HttpClient, rather you can use @WebMVCTest to test your controller. One more thing, you don't need to specify the dependencies by creating objects rather mock them using @MockBean. In code below you specify the exact controller name within @WebMvcTest annotation.

@RunWith(SpringRunner.class)
@WebMvcTest(value = YourController.class, secure = false)
public class YourControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private StudentService rulesService;

    Rule mockRule = new Rule();


    @Test
    public void testLoadOneRule() throws Exception {

        Mockito.when(
                rulesService.loadOneRule(Mockito.anyString(),
                        Mockito.anyString())).thenReturn(mockCourse);

        RequestBuilder requestBuilder = MockMvcRequestBuilders.get(
                "/{ruleId}","rule1")

        MvcResult result = mockMvc.perform(requestBuilder).andReturn();

        System.out.println(result.getResponse());
        String expected = "{id:rule1,name:'RuleName'}";

        JSONAssert.assertEquals(expected, result.getResponse()
                .getContentAsString(), false);
    }

} 

Upvotes: 2

Related Questions