Mohammed Housseyn Taleb
Mohammed Housseyn Taleb

Reputation: 1828

Mocking Repository bean is always null

It has been some hours that I've been trying to test a controller behaviour. The issue is that I have to mock the repository, which always turns to be null.

By a structural view I have a controller that has two injected services, these services uses two different repositories.

So I can test my controller and my services logical behaviour I must mock a repository response to some queries.

I'm trying to achieve it like below:

@WebMvcTest({ WorkspaceRestController.class })
@Tag(Tags.COMPONENT)
@ActiveProfiles(PfSpringProfiles.TEST)
public class WorkspaceRestControllerTest {

    @Autowired
    private MockMvc mockMvc;

    @MockBean
    private IWorkSpaceRepository workSpaceRepository;

    @MockBean
    private IExpertSystemRepository expertSystemRepository;

    @InjectMocks
    private IExpertSystemService expertSystemService;
    
    @InjectMocks
    private IAsyncWorkService asyncWorkspaceService ; 

    @InjectMocks
    private IWorkspaceService workspaceService;

    @InjectMocks
    WorkspaceRestController workspaceRestController;


    @BeforeAll
    public void intTests() {
    }

    @Test
    public void checkRetrievedContentIsNotnull() throws Exception {

        // Given
        Mockito.when(workSpaceRepository.getAllWorkspaces())
                .thenReturn(new WorkSpaceRepositoryMock().getAllWorkspaces(WorkSpaceRepositoryMock.CASE_FULL));
        Mockito.when(expertSystemRepository.getAllLockedEsByWsId(WorkSpaceRepositoryMock.FIRST_WORKSPACE_ID))
                .thenReturn(new ExpertSystemRepositoryMock()
                        .getAllLockedEsByWsId(WorkSpaceRepositoryMock.FIRST_WORKSPACE_ID));
        Mockito.when(expertSystemRepository.getAllLockedEsByWsId(WorkSpaceRepositoryMock.SECOND_WORKSPACE_ID))
                .thenReturn(new ExpertSystemRepositoryMock()
                        .getAllLockedEsByWsId(WorkSpaceRepositoryMock.SECOND_WORKSPACE_ID));
        Mockito.when(expertSystemRepository.getAllLockedEsByWsId(WorkSpaceRepositoryMock.THIRD_WORKSPACE_ID))
                .thenReturn(new ExpertSystemRepositoryMock()
                        .getAllLockedEsByWsId(WorkSpaceRepositoryMock.THIRD_WORKSPACE_ID));

        // When

        MvcResult result = mockMvc.perform(get("/rest/v2/ws-list")).andExpect(request().asyncStarted()).andDo(print())
                .andReturn();

        // Then
        mockMvc.perform(asyncDispatch(result)).andDo(print());
        // .andExpect( content().string(mapper.writeValueAsString(fullWorkspaceResponseSet)));

    }

}

However whenever I launch my JUnit test, the workSpaceRepository is always null.

What should I do?

Below the code of my controller, service and repository

The workspace repository

@Repository
public interface IWorkSpaceRepository extends JpaRepository<Workspace, Long> {
    
    /**
     * This method fetches the list of all available workspaces. It could return an empty list.
     *
     * @return List<Workspace> The list of all workspaces found
     */
    @Transactional
    @Modifying(clearAutomatically = false)
    @Query(value = "SELECT ws from Workspace ws JOIN FETCH ws.configuration")
    List<Workspace> getAllWorkspaces();
}

The workspace service

@Service
public class WorkspaceServiceImp implements IWorkspaceService {

    private static final Logger LOGGER = LoggerFactory.getLogger(WorkspaceServiceImp.class);

    private static final String ERROR_AT_DELETE_WORKSPACE_METHOD = "Error at deleteWorkspace() method";
    private static final String ERROR_AT_CREATE_WORKSPACE_METHOD = "Error at createWorkspace() method";

    @Autowired
    private IWorkSpaceRepository workSpaceRepository;

    @Autowired
    private WorkspaceMapper workspaceMapper;

    @Autowired
    private IExpertSystemService expertSystemService;

    @Autowired
    private IPatternInfosService patternInfosService;

    @Autowired
    private IPatternFieldsService patternFieldsService;

    @Autowired
    private IConfigurationService configurationService;
   
// service methods implementation is ommited
}

The controller

@RestController
@RequestMapping(path = "/rest/ws/")
@Api("WS Service Rest")
@Validated
public class WorkspaceRestController implements RestApiPing {

    private static final Logger LOGGER = LoggerFactory.getLogger(WorkspaceRestController.class);

    @Autowired
    private IWorkspaceService workspaceService;
 

    @Autowired
    private AsyncWorkspaceService asyncWorkspaceService;
 // rest api definition here omited   
 }

The stacktrace I'm getting:

java.lang.NullPointerException
    at com.bnpp.pf.diligense.controller.WorkspaceRestControllerTest.checkRetrievedContentIsNotnull(WorkspaceRestControllerTest.java:65)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    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 org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:80)
    at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:72)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:107)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:88)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:67)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:52)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:95)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:91)
    at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:60)
    at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:98)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:542)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:770)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:464)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:210)

Upvotes: 0

Views: 1883

Answers (1)

Johan Nordlinder
Johan Nordlinder

Reputation: 1886

Add @RunWith(SpringRunner.class) to your test class if you are running junit4 for Mockito to work.

For junit5 the equivalent is @ExtendWith(SpringExtension.class) but that is included in @WebMvcTest so it doesn't need to be explicitly declared.

Upvotes: 4

Related Questions