使用mockito验证对象属性值
我有一个方法调用,我想用mockito来模拟。首先我创建并注入了一个将调用该方法的对象的实例。我的目标是验证方法调用中的一个对象。使用mockito验证对象属性值
有没有一种方法,mockito可以让你断言或验证对象,它的属性,当模拟方法被调用?
例如
Mockito.verify(mockedObject)
.someMethodOnMockedObject(
Mockito.<SomeObjectAsArgument>anyObject())
而不是做anyObject()
我要检查参数对象包含一些特定领域
Mockito.verify(mockedObject)
.someMethodOnMockedObject(
Mockito.<SomeObjectAsArgument>**compareWithThisObject()**)
http://sites.google.com/a/pintailconsultingllc.com/java/argument-matching-with-mockito
此链接提供了一个工作示例。我能够用相同的策略解决它。
了新的功能,以使的Mockito这更容易,
ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
verify(mock).doSomething(argument.capture());
assertEquals("John", argument.getValue().getName());
看看documentation的Mockito
如果你的方法有多个参数,你必须对所有其他参数使用Matchers。 https://akcasoy.wordpress.com/tag/argumentcaptor/ – robsonrosa 2015-08-05 17:07:08
如果有多个参数会怎样?你如何指定你感兴趣的确切人物? – 2017-02-24 14:25:15
@IgorGanapolsky假设你需要做doSomething的第二个String参数:verify(mock).doSomething(argument.capture(),anyString()); – GreenTurtle 2017-04-07 11:23:49
还有一个可能性,如果你不想使用ArgumentCaptor
(例如,因为你'也使用stubbing),就是将Hamcrest Matchers与Mockito结合使用。
import org.mockito.Mockito
import org.hamcrest.Matchers
...
Mockito.verify(mockedObject).someMethodOnMockedObject(Mockito.argThat(
Matchers.<SomeObjectAsArgument>hasProperty("propertyName", desiredValue)));
我想验证一个参数对象最简单的方法是使用refEq
方法:
Mockito.verify(mockedObject).someMethodOnMockedObject(Matchers.refEq(objectToCompareWith));
如果对象没有实现equals()
,由于使用反射它甚至可以使用。如果您不想比较某些字段,只需将其名称添加为refEq
的参数即可。
这是基于answer from iraSenthil的回答,但带有注释(Captor)。在我看来,这有一定的优势:
- 它的短
- 它更易于阅读
- 它可以处理仿制药没有警告
例子:
@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,您可以使用Lambda表达式进行匹配。
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()))));
}
你可以参考以下几点:
Mockito.verify(mockedObject).someMethodOnMockedObject(eq(desiredObject))
这将验证mockedObject的方法是否被调用desiredObject作为参数。
refEq的javadoc提到了相等性检查很浅!您可以在下面的链接的详细信息:
,当您使用不落实.equals()方法的其他类“浅平等”的问题无法控制,“DefaultMongoTypeMapper”级是示例.equals()方法未实现。
org.springframework.beans.factory.support提供了一种可以生成bean定义而不是创建对象实例的方法,它可以用来摆脱比较失败。
genericBeanDefinition(DefaultMongoTypeMapper.class)
.setScope(SCOPE_SINGLETON)
.setAutowireMode(AUTOWIRE_CONSTRUCTOR)
.setLazyInit(false)
.addConstructorArgValue(null)
.getBeanDefinition()
**“的bean定义只是豆腐的描述,而不是豆本身。 豆说明正确实现equals()和hashCode(),这样,而不是创建一个新的DefaultMongoTypeMapper(),我们提供了一个定义,告诉春季应该如何创建一个”
在你的榜样,你可以做somethong这样
Mockito.verify(mockedObject)
.doSoething(genericBeanDefinition(YourClass.class).setA("a")
.getBeanDefinition());
上述的方案并没有真正在我的情况下工作。我无法使用ArgumentCaptor,因为该方法被多次调用,我需要验证每一个。一个简单的匹配器“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);
}
}
测试运行
// 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)));
在链接有以下行`验证(messageSender,和)。发送((名单)argThat(新MessagesArgumentMatcher( )));`不能编译。 –
2016-05-08 07:06:33
@RoeeGavirel你需要“import static org.mockito.Matchers.argThat;” – 2017-07-24 15:11:33