Mockito,如何在同一类上通过引用方法模拟调用



为什么我不能在下面的代码上模拟callRefMethod方法(通过引用调用方法(?问题是实际的callRefMethod方法总是被调用。

public class ManageUserService {
public void callRefMethod(List<String> lsStr, boolean flag){
if (flag){
lsStr.add("one");
lsStr.add("two");
}

}
public void methodA(){
List<String> lsStr = new ArrayList<>();
lsStr.add("zero");
this.callRefMethod(lsStr, true);
for(String str : lsStr){
System.out.println(str);
}
}
}

单元测试:

public class ManageUserServiceTest {
@InjectMocks
private ManageUserService manageUserService;

private AutoCloseable closeable;
@BeforeEach
public void init() {
closeable = MockitoAnnotations.openMocks(this);
}
@AfterEach
void closeService() throws Exception {
closeable.close();
}
@Test
void methodATest(){
List<String> lsData = new ArrayList<>();
lsData.add("start");
ManageUserService manageUserServiceA = new ManageUserService();
ManageUserService userSpy = spy(manageUserServiceA);
doNothing().when(userSpy).callRefMethod(lsData, true);
userSpy.methodA();
verify(userSpy).callRefMethod(ArgumentMatchers.any(ArrayList.class), ArgumentMatchers.any(Boolean.class));
}
}

结果:

zero
one
two

问题在于您在测试方法中创建的列表之间的差异,该列表用于在"无所事事":

List<String> lsData = new ArrayList<>();
lsData.add("start");
...
doNothing().when(userSpy).callRefMethod(lsData, true);

以及在测试方法中创建的列表,传递给间谍对象:

List<String> lsStr = new ArrayList<>();
lsStr.add("zero");
this.callRefMethod(lsStr, true);

如果列表是:["start"],那么您将告诉Mockito给doNothing,但这样的列表永远不会传递给callRefMethod["zero"]被传递到那里,它与期望的参数不匹配,所以实际的方法被调用。

Mockito使用equals将实际参数与预期参数值进行比较-请参阅:文档。为了解决这个问题,可以使用ArgumentMatchers

您可以在测试中修复添加到列表中的值,或者以不太严格的方式匹配预期参数(例如使用anyList()匹配器(。

好的,我使用:其中manageUserServiceOne是ManageUserService类的间谍

void methodATest(){
List<String> lsData = new ArrayList<>();
lsData.add("start");
doAnswer((invocation) -> {
System.out.println(invocation.getArgument(0).toString());
List<String> lsModify = invocation.getArgument(0);
lsModify.add("mockA");
lsModify.add("mockB");
return null;
}).when(manageUserServiceOne).callRefMethod(anyList(), anyBoolean());
manageUserServiceOne.methodA();
verify(manageUserServiceOne).callRefMethod(ArgumentMatchers.any(ArrayList.class), ArgumentMatchers.any(Boolean.class));
}

最新更新