用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更多的细节:
当您使用其他未实现.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)));