0

Hello i am new in Junit mockito
i am trying to write a unit test case but when i am run the test case i am getting null pointer exception.

Code Snip:

package com.dataguise.webservices;

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

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;


import static org.mockito.Mockito.*;

import com.dataguise.cache.CacheManager;
import com.dataguise.controller.CentralController;

import com.dataguise.webservices.beans.DgUserAuthorities;

class RestAPIsTest {


    @InjectMocks
    private CentralController controller;

    @Mock
    DgUserAuthorities dgUserAuthorities;

    @Mock
    private CacheManager cacheManager;


    @BeforeEach
    public void setup() {
        when(this.cacheManager.getCache(anyString())).thenReturn(true);
        MockitoAnnotations.initMocks(this);

    }

    @Test
    void testSession() {
        try {

            dgUserAuthorities = controller.login("d", "d", "", false);
            when(controller.login("d", "d", "", false)).thenReturn(dgUserAuthorities);
            assertEquals(dgUserAuthorities, dgUserAuthorities);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

While the same method call in the rest api gives the appropriate result.

Jony Mittal
  • 151
  • 6
  • 23

1 Answers1

3

There are 2 errors in your test

Error 1: Mixing JUnit4 and JUnit5 annotations

  • org.junit.jupiter.api.Test is from JUnit 5
  • org.junit.Before is from JUnit 4

Thus, your @Before method is never executed. Use org.junit.jupiter.api.BeforeEach instead

Error 2: Using Spring annotations without Spring Extension

@Autowired comes from Spring's DI framework. It will be injected only if you use Spring Injection/ runner

If you want MockitoAnnotations.initMocks(this); to build object under test and inject all mocks, use @InjectMocks

Error 3: confusing way of initializing mocks

There are 2 ways to initialize your mocks:

Manually:

this.dgUserAuthorities = mock(DgUserAuthorities.class);
this.controller = new CentralController(this.dgUserAuthorities);

Using annotations

@InjectMocks
private CentralController controller;

@Mock
DgUserAuthorities dgUserAuthorities;

Annotations require a call to MockitoAnnotations.initMocks(this) or using a Mockito Extension: @ExtendWith(MockitoExtension.class)

I strongly discourage you to mix the 2 approaches. Also, if you use annotations, do not initialize the fields yourself.

Lesiak
  • 22,088
  • 2
  • 41
  • 65
  • One more thing: It's not clear from the original code if controller should be mocked or dgUserAuthorities or both. The way you write it both are mocked but then: What logic are you testing. Yet one more thing: You're when clause comes after the call to the mocked object which cannot work. The `Autowired` and the controller suggests that you actually want to do a Spring integration test... – johanneslink Apr 21 '20 at 08:37
  • i have edit the code please check again but due to cache manager it gives null. – Jony Mittal Apr 21 '20 at 09:23
  • initMocks (creating mocks) must go before setting expectations on them (`when(this.cacheManager.getCache(anyString())).thenReturn(true);`) – Lesiak Apr 21 '20 at 09:31