test mock example java unit-testing junit mockito

java - example - mockito spring



Mockito. Verificar los argumentos del método (8)

He buscado en Google sobre esto, pero no encontré nada relevante. Tengo algo como esto:

Object obj = getObject(); Mockeable mock= Mockito.mock(Mockeable.class); Mockito.when(mock.mymethod(obj )).thenReturn(null); Testeable obj = new Testeable(); obj.setMockeable(mock); command.runtestmethod();

Ahora, quiero verificar que mymethod(Object o) , que se llama inside runtestmethod() , se llamó con el Object o , no con cualquier otro. Pero siempre paso la prueba, sea lo que sea que puse en la verificación, por ejemplo, con:

Mockito.verify(mock.mymethod(Mockito.eq(obj)));

o

Mockito.verify(mock.mymethod(Mockito.eq(null)));

o

Mockito.verify(mock.mymethod(Mockito.eq("something_else")));

Yo siempre paso la prueba. ¿Cómo puedo lograr esa verificación (si es posible)?

Gracias.


¿Estás tratando de hacer la igualdad lógica utilizando el método .equals del objeto? Puedes hacer esto utilizando el parche argThat que está incluido en Mockito

import static org.mockito.Matchers.argThat

A continuación, puede implementar su propio argumento de argumento que diferirá a cada método de objetos .equals

private class ObjectEqualityArgumentMatcher<T> extends ArgumentMatcher<T> { T thisObject; public ObjectEqualityArgumentMatcher(T thisObject) { this.thisObject = thisObject; } @Override public boolean matches(Object argument) { return thisObject.equals(argument); } }

Ahora usando tu código puedes actualizarlo para leer ...

Object obj = getObject(); Mockeable mock= Mockito.mock(Mockeable.class); Mockito.when(mock.mymethod(obj)).thenReturn(null); Testeable obj = new Testeable(); obj.setMockeable(mock); command.runtestmethod(); verify(mock).mymethod(argThat(new ObjectEqualityArgumentMatcher<Object>(obj)));

Si solo busca la igualdad EXACTA (el mismo objeto en la memoria), simplemente haga

verify(mock).mymethod(obj);

Esto verificará que se llamó una vez.


¿Has comprobado el método de iguales para la clase de burla? Si este devuelve siempre verdadero o si prueba la misma instancia contra la misma instancia y el método igual no se sobrescribe (y por lo tanto solo verifica con las referencias), entonces devuelve verdadero.


¿Lo has probado con el mismo () matcher? Como en:

verify(mockObj).someMethod(same(specificInstance));

Yo tuve el mismo problema. Lo intenté con el eq () matcher y con el refEq () matcher, pero siempre tuve falsos positivos. Cuando utilicé el mismo () matcher, la prueba falló cuando los argumentos eran instancias diferentes y pasaron una vez que los argumentos eran la misma instancia.


El otro método es usar el método org.mockito.internal.matchers.Equals.Equals en lugar de redefinir uno:

verify(myMock).myMethod((inputObject)Mockito.argThat(new Equals(inputObjectWanted)));


He usado Mockito.verify de esta manera

@UnitTest public class JUnitServiceTest { @Mock private MyCustomService myCustomService; @Test public void testVerifyMethod() { Mockito.verify(myCustomService, Mockito.never()).mymethod(parameters); // method will never call (an alternative can be pick to use times(0)) Mockito.verify(myCustomService, Mockito.times(2)).mymethod(parameters); // method will call for 2 times Mockito.verify(myCustomService, Mockito.atLeastOnce()).mymethod(parameters); // method will call atleast 1 time Mockito.verify(myCustomService, Mockito.atLeast(2)).mymethod(parameters); // method will call atleast 2 times Mockito.verify(myCustomService, Mockito.atMost(3)).mymethod(parameters); // method will call at most 3 times Mockito.verify(myCustomService, Mockito.only()).mymethod(parameters); // no other method called except this } }


También puede usar TypeSafeDiagnosingMatcher

private Matcher<GetPackagesRequest> expectedPackageRequest(final AvailabilityRequest request) { return new TypeSafeDiagnosingMatcher<GetPackagesRequest>() { StringBuilder text = new StringBuilder(500); @Override protected boolean matchesSafely(GetPackagesRequest req, Description desc) { String productCode = req.getPackageIds().iterator().next().getValue(); if (productCode.equals(request.getSupplierProductCode())) { text.append("ProductCode not equal! " + productCode + " , " + request.getSupplierProductCode()); return true; } text.append(req.toString()); return false; } @Override public void describeTo(Description d) { d.appendText(text.toString()); } }; }

Luego verifica esa invocación:

Mockito.verify(client).getPackages(Mockito.argThat(expectedPackageRequest(request)));


Una alternativa a ArgumentMatcher es ArgumentCaptor .

Ejemplo oficial:

ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class); verify(mock).doSomething(argument.capture()); assertEquals("John", argument.getValue().getName());

Un captor también se puede definir usando la anotación @Captor :

@Captor ArgumentCaptor<Person> captor; //... MockitoAnnotations.initMocks(this); @Test public void test() { //... verify(mock).doSomething(captor.capture()); assertEquals("John", captor.getValue().getName()); }


  • No necesita el eq matcher si no usa otras combinaciones.
  • No está utilizando la sintaxis correcta: su llamada al método debe estar fuera de .verify(mock) . Ahora está iniciando la verificación del resultado de la llamada al método, sin verificar nada (no realizando una llamada a un método). Por lo tanto, todas las pruebas están pasando.

Tu código debería verse así:

Mockito.verify(mock).mymethod(obj); Mockito.verify(mock).mymethod(null); Mockito.verify(mock).mymethod("something_else");