Mockito-NullPointerException al Método stubbing


Así que empecé a escribir pruebas para nuestro proyecto Java-Spring.

Lo que uso es JUnit y Mockito. Se dice que cuando uso el when ()...thenReturn () option I can mock services, without simulating them or so. Así que lo que quiero hacer es, para establecer:

when(classIwantToTest.object.get().methodWhichReturnsAList(input))thenReturn(ListcreatedInsideTheTestClass)  

Pero no importa qué cláusula when lo haga, siempre obtengo una excepción NullPointerException, que por supuesto tiene sentido, porque la entrada es nula.

También cuando trato de burlarse de otro método de un objeto:

when(object.method()).thenReturn(true)

Allí yo también obtener un Nullpointer, porque el método necesita una variable, que no está establecida.

Pero quiero usar when ()..thenReturn () para moverse creando esta variable y así sucesivamente. Solo quiero asegurarme de que si alguna clase llama a este método, entonces no importa qué, solo devuelva true o la lista anterior.

Es básicamente un malentendido de mi parte, o hay algo mal?

Código:

public class classIWantToTest implements classIWantToTestFacade{
        @Autowired
        private SomeService myService;

        @Override
        public Optional<OutputData> getInformations(final InputData inputData) {
            final Optional<OutputData> data = myService.getListWithData(inputData);
            if (data.isPresent()) {
                final List<ItemData> allData = data.get().getItemDatas();
                    //do something with the data and allData
                return data;
            }

            return Optional.absent();
        }   
}

Y aquí está mi clase de prueba:

public class Test {

    private InputData inputdata;

    private ClassUnderTest classUnderTest;

    final List<ItemData> allData = new ArrayList<ItemData>();

    @Mock
    private DeliveryItemData item1;

    @Mock
    private DeliveryItemData item2;



    @Mock
    private SomeService myService;


    @Before
    public void setUp() throws Exception {
        classUnderTest = new ClassUnderTest();
        myService = mock(myService.class); 
        classUnderTest.setService(myService);
        item1 = mock(DeliveryItemData.class);
        item2 = mock(DeliveryItemData.class);

    }


    @Test
    public void test_sort() {
        createData();
        when(myService.getListWithData(inputdata).get().getItemDatas());

        when(item1.hasSomething()).thenReturn(true);
        when(item2.hasSomething()).thenReturn(false);

    }

    public void createData() {
        item1.setSomeValue("val");
        item2.setSomeOtherValue("test");

        item2.setSomeValue("val");
        item2.setSomeOtherValue("value");

        allData.add(item1);
        allData.add(item2);


}
Author: CupawnTae, 2015-10-14

10 answers

El valor de retorno predeterminado de los métodos que aún no se han rellenado es false para los métodos booleanos, una colección o mapa vacío para los métodos que devuelven colecciones o mapas y null de lo contrario.

Esto también se aplica a las llamadas a métodos dentro de when(...). En tu ejemplo when(myService.getListWithData(inputData).get()) provocará un NullPointerException porque myService.getListWithData(inputData) es null - no se ha apagado antes.

Una opción es crear simulaciones para todos los valores de retorno intermedios y pasarlos antes de usarlos. Por ejemplo:

ListWithData listWithData = mock(ListWithData.class);
when(listWithData.get()).thenReturn(item1);
when(myService.getListWithData()).thenReturn(listWithData);

O alternativamente, puede especificar una respuesta predeterminada diferente al crear un mock, para que los métodos devuelvan un nuevo mock en lugar de null: RETURNS_DEEP_STUBS

SomeService myService = mock(SomeService.class, Mockito.RETURNS_DEEP_STUBS);
when(myService.getListWithData().get()).thenReturn(item1);

Deberías leer el Javadoc de Mockito.RETURNS_DEEP_STUBS que explica esto con más detalle y también tiene algunas advertencias sobre su uso.

Espero que esto ayude. Solo tenga en cuenta que su código de ejemplo parece tener más problemas, como la falta de declaraciones assert o verify y llamar a los configuradores en simks (que no tiene ninguna efecto).

 31
Author: ahu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-08-23 09:23:16

Tuve este problema y mi problema era que estaba llamando a mi método con any() en lugar de anyInt(). Así que tuve:

doAnswer(...).with(myMockObject).thisFuncTakesAnInt(any())

Y tuve que cambiarlo a:

doAnswer(...).with(myMockObject).thisFuncTakesAnInt(anyInt())

No tengo idea de por qué eso produjo una excepción NullPointerException. Tal vez esto ayude a la próxima pobre alma.

 46
Author: Ryan Shillington,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-02 21:27:38

Tuve el mismo problema y mi problema fue simplemente que no había anotado la clase correctamente usando @RunWith. En tu ejemplo, asegúrate de que tienes:

@RunWith(MockitoJUnitRunner.class)
public class Test {
...

Una vez que hice eso, las NullPointerExceptions desaparecieron.

 23
Author: Ed Webb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-15 17:00:44

Caja de esquina:
Si estás usando Scala y tratas de crear un any matcher en una clase de valor , obtendrás un NPE inútil.

Así que dado case class ValueClass(value: Int) extends AnyVal, lo que quieres hacer es ValueClass(anyInt) en lugar de any[ValueClass]

when(mock.someMethod(ValueClass(anyInt))).thenAnswer {
   ...
   val v  = ValueClass(invocation.getArguments()(0).asInstanceOf[Int])
   ...
}

Este otro SO question es más específicamente sobre eso, pero lo echarías de menos cuando no sabes que el problema es con las clases de valor.

 2
Author: Vituel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-19 10:17:54

Para mí, la razón por la que obtenía NPE es que estaba usando Mockito.any() cuando me burlaba de primitivas. Descubrí que al cambiar a usar la variante correcta de mockito se deshace de los errores.

Por ejemplo, para simular una función que toma un primitivo long como parámetro, en lugar de usar any(), debe ser más específico y reemplazarlo con any(Long.class) o Mockito.anyLong().

Espero que eso ayude a alguien.

Salud

 2
Author: smac89,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-03 15:53:43
@RunWith(MockitoJUnitRunner.class) //(OR) PowerMockRunner.class

@PrepareForTest({UpdateUtil.class,Log.class,SharedPreferences.class,SharedPreferences.Editor.class})
public class InstallationTest extends TestCase{

@Mock
Context mockContext;
@Mock
SharedPreferences mSharedPreferences;
@Mock
SharedPreferences.Editor mSharedPreferenceEdtor;

@Before
public void setUp() throws Exception
{
//        mockContext = Mockito.mock(Context.class);
//        mSharedPreferences = Mockito.mock(SharedPreferences.class);
//        mSharedPreferenceEdtor = Mockito.mock(SharedPreferences.Editor.class);
    when(mockContext.getSharedPreferences(Mockito.anyString(),Mockito.anyInt())).thenReturn(mSharedPreferences);
    when(mSharedPreferences.edit()).thenReturn(mSharedPreferenceEdtor);
    when(mSharedPreferenceEdtor.remove(Mockito.anyString())).thenReturn(mSharedPreferenceEdtor);
    when(mSharedPreferenceEdtor.putString(Mockito.anyString(),Mockito.anyString())).thenReturn(mSharedPreferenceEdtor);
}

@Test
public void deletePreferencesTest() throws Exception {

 }
}

No se requieren todos los códigos comentados anteriormente { mockContext = Mockito.mock(Context.class); }, si usa @ Mock Anotación a Context mockContext;

 @Mock 
 Context mockContext; 

Pero funcionará si usas @RunWith(MockitoJUnitRunner.class) solamente. De acuerdo con Mockito, puede crear un objeto mock usando @Mock o Mockito.mock (Context.clase); ,

Obtuve NullPointerException debido al uso de @RunWith(PowerMockRunner.class), en lugar de eso cambié a @RunWith (MockitoJUnitRunner.class) funciona fine

 1
Author: anand krish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-04-04 07:05:22

Para futuros lectores, otra causa de NPE cuando se usan mock es olvidarse de inicializar los mock de esta manera:

@Mock
SomeMock someMock;

@InjectMocks
SomeService someService;

@Before
public void setup(){
    MockitoAnnotations.initMocks(this); //without this you will get NPE
}

@Test
public void someTest(){
    Mockito.when(someMock.someMethod()).thenReturn("some result");
   // ...
}
 1
Author: Tal Joffe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-03 17:29:46

Se enfrentó al mismo problema, la solución que funcionó para mí:

En lugar de burlarme de la interfaz del servicio, usé @InjectMocks para burlarme de la implementación del servicio:

@InjectMocks
private exampleServiceImpl exampleServiceMock;

En lugar de :

@Mock
private exampleService exampleServiceMock;
 0
Author: Ajay Vijayasarathy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-22 01:43:05

La respuesta de Ed Webb ayudó en mi caso. Y en su lugar, también puede probar add

  @Rule public Mocks mocks = new Mocks(this);

Si usted @RunWith(JUnit4.class).

 0
Author: lcn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-25 03:35:27

En mi caso, me perdí agregar primero

PowerMockito.spy(ClassWhichNeedToBeStaticMocked.class);

Así que esto puede ser útil para alguien que ve tal error

java.lang.NullPointerException
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.addAnswersForStubbing(PowerMockitoStubberImpl.java:67)
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:42)
    at org.powermock.api.mockito.internal.expectation.PowerMockitoStubberImpl.when(PowerMockitoStubberImpl.java:112)
 0
Author: Serhii Bohutskyi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-28 13:51:07