0

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)
7
  • 1
    Don't create an instance of the RuleService ou will need to auto wired one. If you still get exceptions post that exception. Any reason you aren't simply using the RestTemplate or MockMvc to test your controller? Commented Sep 4, 2018 at 7:54
  • @M.Deinum They said it would be easier not to mock al the objects. I am running my project locally and successfully made 3 tests for HTTP GET but this one looks trickier since I must have the object in database to get it's mongo id so the URL to end on this String . I did try to autowire the ruleService and I have the same problem with nullpointer exception on same line of code. Commented Sep 4, 2018 at 7:57
  • Where do I state you need to mock all your objects? Post the null pointer and your actual testcase. Commented Sep 4, 2018 at 7:58
  • 1
    Well then creating or auto wiring the RuleService will not work/help. You need to retrieve a rule that us available at the server not local to your test. Commented Sep 4, 2018 at 8:14
  • 1
    No. As your service is running on tomcat and not local to your test. Commented Sep 4, 2018 at 8:30

1 Answer 1

2

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);
    }

} 
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.