用mockitovalidation对象的属性值

我有一个方法调用,我想嘲笑与mockito。 首先我创build并注入了一个将调用该方法的对象的实例。 我的目的是validation方法调用中的一个对象。

有没有一种方式,mockito可以让你断言或validation对象,它的属性时,调用模拟方法?

Mockito.verify(mockedObject) .someMethodOnMockedObject( Mockito.<SomeObjectAsArgument>anyObject()) 

而不是做anyObject()我想检查参数对象包含一些特定的领域

 Mockito.verify(mockedObject) .someMethodOnMockedObject( Mockito.<SomeObjectAsArgument>**compareWithThisObject()**) 

添加到Mockito的新function使这更容易,

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

看看Mockito 文档

如果你不想使用ArgumentCaptor (例如,因为你也使用了stubbing),另一种可能性就是使用Hamcrest Matchers和Mockito。

 import org.mockito.Mockito import org.hamcrest.Matchers ... Mockito.verify(mockedObject).someMethodOnMockedObject(Mockito.argThat( Matchers.<SomeObjectAsArgument>hasProperty("propertyName", desiredValue))); 

我认为validation参数对象最简单的方法是使用refEq方法:

 Mockito.verify(mockedObject).someMethodOnMockedObject(Matchers.refEq(objectToCompareWith)); 

即使对象没有实现equals() ,也可以使用它,因为使用了reflection。 如果您不想比较某些字段,只需将它们的名称添加为refEq参数refEq

http://sites.google.com/a/pintailconsultingllc.com/java/argument-matching-with-mockito

此链接提供了一个工作示例。 我能够用同样的策略来解决这个问题。

这是基于来自iraSenthil的回答,但带有注解( Captor )。 我认为它有一些优点:

  • 它更短
  • 它更容易阅读
  • 它可以处理generics没有警告

例:

 @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")); } } 

如果您使用Java 8,则可以使用Lambdaexpression式进行匹配。

 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); } } 

示例调用

 @Test public void canFindEmployee() { Employee employee = new Employee("John"); company.addEmployee(employee); verify(mockedDal).registerEmployee(argThat(new LambdaMatcher<>(e -> e.getName() .equals(employee.getName())))); } 

更多信息: http : //source.coveo.com/2014/10/01/java8-mockito/

你可以参考以下内容:

 Mockito.verify(mockedObject).someMethodOnMockedObject(eq(desiredObject)) 

这将validation是否以desiredObject作为参数调用mockedObject的方法。

refEq的javadoc提到平等检查是浅的! 你可以在下面的链接中find更多的细节:

[ https://static.javadoc.io/org.mockito/mockito-core/2.2.29/org/mockito/ArgumentMatchers.html#refEq(T,%20java.lang.String…)][1]

当您使用其他未实现.equals()方法的类时,“浅层次”问题无法控制,“DefaultMongoTypeMapper”类是未实现.equals()方法的示例。

org.springframework.beans.factory.support提供了一个方法,可以生成一个bean的定义,而不是创build一个对象的实例,它可以用来摆脱比较失败。

  genericBeanDefinition(DefaultMongoTypeMapper.class) .setScope(SCOPE_SINGLETON) .setAutowireMode(AUTOWIRE_CONSTRUCTOR) .setLazyInit(false) .addConstructorArgValue(null) .getBeanDefinition() 

**“bean的定义只是对bean的描述,而不是对bean本身的描述,bean描述正确地实现了equals()和hashCode(),所以不是创build一个新的DefaultMongoTypeMapper()应该创造一个“

在你的例子中,你可以像这样做一些事情

 Mockito.verify(mockedObject) .doSoething(genericBeanDefinition(YourClass.class).setA("a") .getBeanDefinition()); 

上面的解决scheme在我的情况下并不起作用。 我不能使用ArgumentCaptor,因为这个方法被多次调用,我需要validation每一个。 一个简单的匹配“argThat”很容易做到这一点。

自定义匹配器

 // 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); } } 

testing赛跑者

 // 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)));