java - uso - Verifique el valor del atributo objeto con mockito.
tutorial mockito java (9)
¡El javadoc para refEq mencionó que el control de igualdad es superficial! Puedes encontrar más detalles en el siguiente enlace:
el problema de "igualdad superficial" no se puede controlar cuando utiliza otras clases que no implementan el método .equals (), la clase "DefaultMongoTypeMapper" es un ejemplo donde el método .equals () no está implementado.
org.springframework.beans.factory.support ofrece un método que puede generar una definición de bean en lugar de crear una instancia del objeto, y se puede usar para deshacerse de la falla de comparación.
genericBeanDefinition(DefaultMongoTypeMapper.class)
.setScope(SCOPE_SINGLETON)
.setAutowireMode(AUTOWIRE_CONSTRUCTOR)
.setLazyInit(false)
.addConstructorArgValue(null)
.getBeanDefinition()
** "La definición de bean es solo una descripción del bean, no un bean en sí mismo. Las descripciones de bean implementan adecuadamente equals () y hashCode (), así que en lugar de crear un nuevo DefaultMongoTypeMapper () proporcionamos una definición que le indica a Spring cómo debe crear uno "
En tu ejemplo, puedes hacer algo así.
Mockito.verify(mockedObject)
.doSoething(genericBeanDefinition(YourClass.class).setA("a")
.getBeanDefinition());
Tengo un método de llamada del que quiero burlarme con mockito. Para empezar, he creado e inyectado una instancia de un objeto en el que se llamará el método. Mi objetivo es verificar uno de los objetos en el método de llamada.
¿Hay alguna manera en que mockito le permita afirmar o verificar el objeto y sus atributos cuando se llama al método simulado?
ejemplo
Mockito.verify(mockedObject)
.someMethodOnMockedObject(
Mockito.<SomeObjectAsArgument>anyObject())
En lugar de hacer anyObject()
quiero comprobar que el objeto de argumento contiene algunos campos en particular
Mockito.verify(mockedObject)
.someMethodOnMockedObject(
Mockito.<SomeObjectAsArgument>**compareWithThisObject()**)
Creo que la forma más fácil de verificar un objeto de argumento es usar el método refEq
:
Mockito.verify(mockedObject).someMethodOnMockedObject(Matchers.refEq(objectToCompareWith));
Se puede usar incluso si el objeto no implementa equals()
, porque se usa la reflexión. Si no desea comparar algunos campos, solo agregue sus nombres como argumentos para refEq
.
Esta es una respuesta basada en la respuesta de iraSenthil pero con anotación ( Captor ). En mi opinión tiene algunas ventajas:
- es mas corto
- es más fácil de leer
- Puede manejar genéricos sin advertencias.
Ejemplo:
@RunWith(MockitoJUnitRunner.class)
public class SomeTest{
@Captor
private ArgumentCaptor<List<SomeType>> captor;
//...
@Test
public void shouldTestArgsVals() {
//...
verify(mockedObject).someMethodOnMockedObject(captor.capture());
assertThat(captor.getValue().getXXX(), is("expected"));
}
}
La nueva característica agregada a Mockito hace esto aún más fácil,
ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
verify(mock).doSomething(argument.capture());
assertEquals("John", argument.getValue().getName());
Echa un vistazo a la documentation Mockito.
Las soluciones anteriores no funcionaron en mi caso. No pude usar ArgumentCaptor ya que el método fue llamado varias veces y necesitaba validar cada uno. Un simple Matcher con "argThat" hizo el truco fácilmente.
Matcher personalizado
// custom matcher
private class PolygonMatcher extends ArgumentMatcher<PolygonOptions> {
private int fillColor;
public PolygonMatcher(int fillColor) {
this.fillColor = fillColor;
}
@Override
public boolean matches(Object argument) {
if (!(argument instanceof PolygonOptions)) return false;
PolygonOptions arg = (PolygonOptions)argument;
return Color.red(arg.getFillColor()) == Color.red(fillColor)
&& Color.green(arg.getFillColor()) == Color.green(fillColor)
&& Color.blue(arg.getFillColor()) == Color.blue(fillColor);
}
}
Corredor de prueba
// do setup work setup
// 3 light green polygons
int green = getContext().getResources().getColor(R.color.dmb_rx_bucket1);
verify(map, times(3)).addPolygon(argThat(new PolygonMatcher(green)));
// 1 medium yellow polygons
int yellow = getContext().getResources().getColor(R.color.dmb_rx_bucket4);
verify(map, times(1)).addPolygon(argThat(new PolygonMatcher(yellow)));
// 3 red polygons
int orange = getContext().getResources().getColor(R.color.dmb_rx_bucket5);
verify(map, times(3)).addPolygon(argThat(new PolygonMatcher(orange)));
// 2 red polygons
int red = getContext().getResources().getColor(R.color.dmb_rx_bucket7);
verify(map, times(2)).addPolygon(argThat(new PolygonMatcher(red)));
Puede referirse a lo siguiente:
Mockito.verify(mockedObject).someMethodOnMockedObject(eq(desiredObject))
Esto verificará si se llama al método de mockedObject con desiredObject como parámetro.
Si está utilizando Java 8, puede usar expresiones Lambda para hacer coincidir.
import java.util.Optional;
import java.util.function.Predicate;
import org.hamcrest.BaseMatcher;
import org.hamcrest.Description;
public class LambdaMatcher<T> extends BaseMatcher<T>
{
private final Predicate<T> matcher;
private final Optional<String> description;
public LambdaMatcher(Predicate<T> matcher)
{
this(matcher, null);
}
public LambdaMatcher(Predicate<T> matcher, String description)
{
this.matcher = matcher;
this.description = Optional.ofNullable(description);
}
@SuppressWarnings("unchecked")
@Override
public boolean matches(Object argument)
{
return matcher.test((T) argument);
}
@Override
public void describeTo(Description description)
{
this.description.ifPresent(description::appendText);
}
}
Ejemplo de llamada
@Test
public void canFindEmployee()
{
Employee employee = new Employee("John");
company.addEmployee(employee);
verify(mockedDal).registerEmployee(argThat(new LambdaMatcher<>(e -> e.getName()
.equals(employee.getName()))));
}
Más información: http://source.coveo.com/2014/10/01/java8-mockito/
Una posibilidad más, si no quieres usar ArgumentCaptor
(por ejemplo, porque también estás usando stubbing), es usar Hamcrest Matchers en combinación con Mockito.
import org.mockito.Mockito
import org.hamcrest.Matchers
...
Mockito.verify(mockedObject).someMethodOnMockedObject(Mockito.argThat(
Matchers.<SomeObjectAsArgument>hasProperty("propertyName", desiredValue)));
http://sites.google.com/a/pintailconsultingllc.com/java/argument-matching-with-mockito
Este enlace proporciona un ejemplo de trabajo. Pude resolverlo con la misma estrategia.