我有一个方法(method1)我想测试,它根据提供的参数创建一个对象并调用另一个方法(method2)。所以我在模拟方法2,它接受一个对象(sampleObj)。
public void method1(booleanParam) {
if(booleanParam){
List<SampleObj> fooList = new ArrayList<SampleObj>;
fooList.add(new SampleObj("another param"));
anotherService.method2(fooList);
}
//some other smart logic here
}
这是我使用相同的混淆名称的测试(抱歉,如果我错过了任何拼写错误):
public void testMethod1() {
AnotherService mockedAnotherService = PowerMockito.mock(AnotherService.class);
ServicesFactory.getInstance().setMock(AnotherService.class, mockedAnotherService);
List<SampleObj> fooList = new ArrayList<SampleObj>;
fooList.add(new SampleObj("another param"));
// assert and verify
service.method1(true);
Mockito.verify(mockedAnotherService, times(1)).method2(fooList);
}
问题是,当我尝试模拟另一个服务时,我需要将一个对象传递给 method2,所以我必须创建一个新对象。但由于它是一个新对象,它不是同一个对象,它将从 method1 内部传递,因此测试失败并出现异常:
Argument(s) are different! Wanted:
anotherService.method2(
[com.smart.company.SampleObj@19c59e46]
);
-> at <test filename and line # here>
Actual invocation has different arguments:
anotherService.method2(
[com.smart.company.SampleObj@7d1a12e1]
);
-> at <service filename and line # here>
有什么想法吗?
您有几个选择:
-
在
SampleObj
上实施equals
和hashCode
。由于您没有将fooList
包装在匹配器中,因此 Mockito 会检查List.equals
,这会检查每个列表中是否有相应的对象equals
。Object.equals 的默认行为是a.equals(b)
iffa == b
- 也就是说,对象是相等的,如果它们引用相同的实例 - 但如果每个 SampleObj("foobar") 等于每个其他 SampleObj("foobar"),欢迎您覆盖它。 -
使用您编写的Hamcrest Matcher。
private static Matcher<List<SampleObj>> isAListWithObjs(String... strings) { return new AbstractMatcher<List<SampleObj>>() { @Override public boolean matches(Object object) { // return true if object is a list of SampleObj corresponding to strings } }; } // in your test verify(mockedAnotherService).method2(argThat(isAnObjListWith("another param")));
请注意,您也可以只制作单个 SampleObj 的匹配器,然后使用 Hamcrest 包装器,如
hasItem
。在此处查看更多匹配器。 -
使用捕获者以您自己的方式检查
equals
:public class YourTest { // Populated with MockitoAnnotations.initMocks(this). // You can also use ArgumentCaptor.forClass(...), but with generics trouble. @Captor ArgumentCaptor<List<SampleObj>> sampleObjListCaptor; @Test public void testMethod1() { // ... verify(mockedAnotherService).method2(sampleObjListCaptor.capture()); List<SampleObj> sampleObjList = sampleObjListCaptor.getValue(); assertEquals(1, sampleObjList.size()); assertEquals("another param", sampleObjList.get(0).getTitle()); }