Why i can not mock callReffMethod method (call method by refference) on below code ? the problem is real method of callReffMethod always being called.
public class ManageUserService {
public void callReffMethod(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.callReffMethod(lsStr, true);
for(String str : lsStr){
System.out.println(str);
}
}
}
//Unit Test:
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).callReffMethod(lsData, true);
userSpy.methodA();
verify(userSpy).callReffMethod(ArgumentMatchers.any(ArrayList.class), ArgumentMatchers.any(Boolean.class));
}
}
//The result : zero one two
CodePudding user response:
The problem is the difference between the list you're creating in the test method, which is used to match the expected parameters when "doing nothing":
List<String> lsData = new ArrayList<>();
lsData.add("start");
...
doNothing().when(userSpy).callReffMethod(lsData, true);
and the list created in the tested method, passed to the spy object:
List<String> lsStr = new ArrayList<>();
lsStr.add("zero");
this.callReffMethod(lsStr, true);
You're telling Mockito to doNothing
if the list is: ["start"]
, but such list is never passed to the callReffMethod
. ["zero"]
is passed there, which does not match the expected params, so actual method is called.
Mockito uses equals
to compare the actual argument with an expected parameter value - see: the documentation. To work around that ArgumentMatchers
can be used.
You can either fix the value added to the list in the test or match the expected parameter in a less strict way (e.g. using anyList()
matcher).
CodePudding user response:
ok i did it by using : where manageUserServiceOne is spy of ManageUserService class
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).callReffMethod(anyList(), anyBoolean());
manageUserServiceOne.methodA();
verify(manageUserServiceOne).callReffMethod(ArgumentMatchers.any(ArrayList.class), ArgumentMatchers.any(Boolean.class));
}