Home » Java » java – NPE returned by a mocked function spring boot-Exceptionshub

java – NPE returned by a mocked function spring boot-Exceptionshub

Posted by: admin February 25, 2020 Leave a comment

Questions:

I’m new to testing and I’m trying to learn unit testing using JUnit and spring boot and that exception popped up.
As you can see I mocked the behavior of the function I needed in the TopicSevices but I still get this NPE, I also tried to add

MockitoAnnotations.initMocks(this);

But it didn’t work.

The controller code

package com.example.test.controller;

import java.util.List;

import javax.validation.Valid;

import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.example.test.Services.ExerciceServices;
import com.example.test.Services.TopicService;
import com.example.test.model.Difficulty;
import com.example.test.model.Exercice;
import com.example.test.model.Status;
import com.example.test.model.dto.ExerciceDTO;

@CrossOrigin("*")
@RestController
public class ExerciceController {

    private final ExerciceServices exerciceServices;
    private final TopicService topicServices;

    public ExerciceController(ExerciceServices exerciceServices, TopicService topicServices) {

        this.exerciceServices = exerciceServices;
        this.topicServices = topicServices;
    }

    @GetMapping("/exercices")
    public List<Exercice> allExercices() {
        return exerciceServices.getAllExecices();
    }

    @PostMapping("/exercices")
    public Exercice createExercice(@Valid @RequestBody ExerciceDTO dto) {

        Exercice exercice = createExcerciceFromDto(dto);

        return exerciceServices.CreateeExercice(exercice);
    }

    public Exercice createExcerciceFromDto(ExerciceDTO dto) {

        Exercice exercice = new Exercice();

        exercice.setDifficulty(dto.getDifficulty());
        exercice.setImg(dto.getImg());
        exercice.setStatus(dto.getStatus());
        exercice.setTitle(dto.getTitle());

        for (Long id : dto.getListToppicId()) {
            try {
                System.out.println(topicServices.getTopicById(id));
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return exercice;
    }

    @GetMapping("/exercices/filter")
    public List<Exercice> getExeerciceByDifficulty(@RequestParam(required = false) Long id,
            @RequestParam Difficulty difficulty, @RequestParam Status status) {

        return exerciceServices.exercicesFilterTopic(id, difficulty, status);

    }

}

The test code

package com.example.test.controller;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Optional;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.test.web.servlet.MockMvc;

import com.example.test.Services.ExerciceServices;
import com.example.test.Services.TopicService;
import com.example.test.model.Difficulty;
import com.example.test.model.Exercice;
import com.example.test.model.Status;
import com.example.test.model.Topic;
import com.example.test.model.dto.ExerciceDTO;

@RunWith(MockitoJUnitRunner.class)
@WebMvcTest

class ExerciceControllerTest {


    @MockBean
    private ExerciceServices exerciceServices;

    @MockBean
    private TopicService topicServices;

    @InjectMocks
    private ExerciceController exerciceController;

    ExerciceDTO dto = new ExerciceDTO();
    Exercice e = new Exercice();
    Topic t = new Topic();

    @BeforeEach
    public void setUp() throws Exception {
        Mockito.when(exerciceServices.getAllExecices()).thenReturn(Arrays.asList(e));
    }

    @Test
    public void givenDTOCreateTheExercice() {
        dto.setDifficulty(Difficulty.EASY);
        dto.setImg("link");
        dto.setStatus(Status.FINISHED);
        dto.setTitle("title");
        dto.setListToppicId(new HashSet<>(Arrays.asList(6L)));

        e.setDifficulty(Difficulty.EASY);
        e.setImg("link");
        e.setStatus(Status.FINISHED);
        e.setTitle("title");

        t.setId(6L);
        t.setTitle("romayssae");

        e.setTopics(new HashSet<>(Arrays.asList(t)));
        Optional<Topic> topic = Optional.of(t);

        Mockito.when(topicServices.getTopicById(6L)).thenReturn(topic);

        System.out.println(topicServices.getTopicById(6L));

        assertEquals(e, exerciceController.createExcerciceFromDto(dto));
    }


}

The Exception

java.lang.NullPointerException
    at com.example.test.controller.ExerciceController.createExcerciceFromDto(ExerciceController.java:58)
    at com.example.test.controller.ExerciceControllerTest.givenDTOCreateTheExercice(ExcerciceControllerTest.java:77)
    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.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:675)
    at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:125)
    at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:132)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:124)
    at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:74)
    at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:104)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:62)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:43)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:35)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:104)
    at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:98)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:202)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:198)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:135)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:69)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:135)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1540)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137)
    at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)
How to&Answers:

try to use @Mock instead of @MockBean. It should be ok

Answer:

I tried this and it worked for me, however, I did understand why.
In short, I changed the @Mock instead of @MockBean as suggested by @arbuzov. Then I got this exception java.lang.IllegalStateException: Failed to load ApplicationContext, to solve this I added this two annotations @SpringBootTest
@AutoConfigureMockMvc
.
Then I tried to test another method using the MockMvc there again the mocked behavior was ignored somehow, so I changed back to @MockBean which worked.
If someone understands why/how it worked please help me understand how it works and thank you ^^ .

package com.example.test.controller;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import java.util.Arrays;
import java.util.HashSet;
import java.util.Optional;

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;

import com.example.test.Services.ExerciceServices;
import com.example.test.Services.TopicService;
import com.example.test.model.Difficulty;
import com.example.test.model.Exercice;
import com.example.test.model.Status;
import com.example.test.model.Topic;
import com.example.test.model.dto.ExerciceDTO;

@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc

class ExerciceControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private ExerciceServices exerciceServices;

    @Mock
    private TopicService topicServices;

    @InjectMocks
    private ExerciceController exerciceController;

    ExerciceDTO dto = new ExerciceDTO();
    Exercice e = new Exercice();
    Topic t = new Topic();

    @BeforeEach
    public void setUp() throws Exception {

    }

    @Test
    public void givenDTOCreateTheExercice() {

        assertEquals(e, exerciceController.createExcerciceFromDto(dto));
    }

    @Test
    public void eznekfnzre() throws Exception {
        dto.setDifficulty(Difficulty.EASY);
        dto.setImg("link");
        dto.setStatus(Status.FINISHED);
        dto.setTitle("title");
        dto.setListToppicId(new HashSet<>(Arrays.asList(6L)));

        e.setDifficulty(Difficulty.EASY);
        e.setImg("link");
        e.setStatus(Status.FINISHED);
        e.setTitle("title");

        t.setId(6L);
        t.setTitle("romayssae");

        e.setTopics(new HashSet<>(Arrays.asList(t)));
        Optional<Topic> topic = Optional.of(t);

        Mockito.when(topicServices.getTopicById(6L)).thenReturn(topic);
        Mockito.when(exerciceServices.getAllExecices()).thenReturn(Arrays.asList(e));
        mockMvc.perform(get("/exercices/").contentType(MediaType.APPLICATION_JSON)).andExpect(status().isOk())
                .andExpect(jsonPath("$[0].title", is(e.getTitle())));
    }

}