Pri*_*ank 243 java mocking mockito
我有一个方法调用,我想用mockito模拟.首先,我创建并注入了一个将在其上调用方法的对象实例.我的目的是验证方法调用中的一个对象.
有没有一种方法可以让mockito在调用mock方法时断言或验证对象及其属性?
例
Mockito.verify(mockedObject)
.someMethodOnMockedObject(
Mockito.<SomeObjectAsArgument>anyObject())
Run Code Online (Sandbox Code Playgroud)
而不是anyObject()我想检查该参数对象包含一些特定的字段
Mockito.verify(mockedObject)
.someMethodOnMockedObject(
Mockito.<SomeObjectAsArgument>**compareWithThisObject()**)
Run Code Online (Sandbox Code Playgroud)
ira*_*hil 498
Mockito新增的功能使这更容易,
ArgumentCaptor<Person> argument = ArgumentCaptor.forClass(Person.class);
verify(mock).doSomething(argument.capture());
assertEquals("John", argument.getValue().getName());
Run Code Online (Sandbox Code Playgroud)
看看Mockito 文档
Joh*_*n29 54
我认为验证参数对象的最简单方法是使用该refEq方法:
Mockito.verify(mockedObject).someMethodOnMockedObject(Matchers.refEq(objectToCompareWith));
Run Code Online (Sandbox Code Playgroud)
即使对象未实现equals(),也可以使用它,因为使用了反射.如果您不想比较某些字段,只需将它们的名称添加为参数refEq.
cha*_*eyc 45
ArgumentCaptor另一种可能性,如果你不想使用(例如,因为你也使用了存根),就是将Hamcrest Matchers与Mockito结合使用.
import org.mockito.Mockito
import org.hamcrest.Matchers
...
Mockito.verify(mockedObject).someMethodOnMockedObject(Mockito.argThat(
Matchers.<SomeObjectAsArgument>hasProperty("propertyName", desiredValue)));
Run Code Online (Sandbox Code Playgroud)
Wal*_*uch 16
这是基于来自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"));
}
}
Run Code Online (Sandbox Code Playgroud)
如果您使用的是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);
}
}
Run Code Online (Sandbox Code Playgroud)
示例电话
@Test
public void canFindEmployee()
{
Employee employee = new Employee("John");
company.addEmployee(employee);
verify(mockedDal).registerEmployee(argThat(new LambdaMatcher<>(e -> e.getName()
.equals(employee.getName()))));
}
Run Code Online (Sandbox Code Playgroud)
更多信息:http://source.coveo.com/2014/10/01/java8-mockito/
一种简化的解决方案,无需创建新的 Matcher 实现类和使用 lambda 表达式:
verify(mockObject).someMockMethod(
argThat((SomeArgument arg) -> arg.fieldToMatch.equals(expectedFieldValue)));
Run Code Online (Sandbox Code Playgroud)
上面的解决方案在我的情况下并没有真正起作用。我无法使用 ArgumentCaptor,因为该方法被多次调用,我需要验证每一个。一个简单的带有“argThat”的 Matcher 很容易做到这一点。
自定义匹配器
// 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);
}
}
Run Code Online (Sandbox Code Playgroud)
测试运行器
// 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)));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
168516 次 |
| 最近记录: |