英文:
Java Mockito - verify method called with reference type parameter
问题
你可以使用Mockito
的eq()
方法来处理类类型参数的匹配。在你的示例中,你可以像这样使用它:
when(MyUtils.getUserFromOtherPlace(eq(UserType.ADMIN))).thenReturn(adminUser);
这应该能够解决你的问题。这里的eq()
方法用于匹配参数,确保参数与预期的一致。希望这对你有所帮助!
英文:
I am new to using Mockito while I am verifying certain method should be called with a specific parameter, while all the value type parameter (int, String, enum etc) could be verified, but reference/class type parameter seems not, here is an example
// my actual class
public class MyActualClass {
public void processRequest() {
User curUser = MyUtils.getUserFromOtherPlace(UserType.ADMIN);
processAnotherRequest(1, "address", curUser);
}
public void processAnotherRequest(int userId, String address, User user) { ... }
}
public static class MyUtils{
public static getUserFromOtherPlace(UserType userType) {
User newUser = new User();
if (userType == UserType.ADMIN) {
newUser.setAccess(1);
}
//...
return newUser
}
}
// my test class
public class MyActualClassTest{
@Mock
private MyActualClass myActualClass;
@Test
public void testIfMethodBeingCalledCorrectly() {
User adminUser = new User();
adminUser.setAccess(1);
doCallRealMethod().when(myActualClass).processRequest();
myActualClass.processRequest();
verify(myActualClass).processAnotherRequest(1, "address", adminUser);
}
}
I know it might because the adminUser
set in my test method was not the same reference object that'd be generated through my actual method getUserFromOtherPlace -> MyUtils.getUserFromOtherPlace, I also tried to mock the return object with my static method like
// tried 1
when(MyUtils.getUserFromOtherPlace(UserType.ADMIN).thenReturn(adminUser); // this throws error like "You cannot use argument matchers outside of verification or stubbing", and suggest using eq()
// tried 2
when(MyUtils.getUserFromOtherPlace(eq(UserType.ADMIN)).thenReturn(adminUser); //this throws NullPointer exception in getUserFromOtherPlace when check the input enum parameter "userType"
So how could I pass the reference object into my entry method and mock it as return value of my internal method here? BTW, if my method only contains value type parameter, it will work...
答案1
得分: 1
为了模拟静态方法,您需要:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ MyUtils.class })
// 在这里放入您的测试类
@Before
public void setup() {
PowerMockito.mockStatic(MyUtils.class);
when(MyUtils.getUserFromOtherPlace(UserType.ADMIN)).thenReturn(adminUser);
}
但是,如果有其他选项,我总是更喜欢不模拟静态类,也许您可以尝试使用参数捕获器:
// 测试类
@Captor
private ArgumentCaptor<User> captor;
// 您的测试方法
@Test
public void testIfMethodBeingCalledCorrectly() {
doCallRealMethod().when(myActualClass).processRequest();
myActualClass.processRequest();
verify(myActualClass, times(1)).processAnotherRequest(1, "address",
captor.capture());
Assert.assertEquals(1, captor.getValue().getAccess());
}
英文:
So in order to mock you static method you will need to:
@RunWith(PowerMockRunner.class)
@PrepareForTest({ MyUtils.class })
//your test class here
@Before
public void setup() {
PowerMockito.mockStatic(MyUtils.class);
when(MyUtils.getUserFromOtherPlace(UserType.ADMIN).thenReturn(adminUser);
}
But I always prefer not to mock static classes if there is another option so maybe you could try a argument captor:
//test class
@Captor
private ArgumentCaptor<User> captor;
//your test
@Test
public void testIfMethodBeingCalledCorrectly() {
doCallRealMethod().when(myActualClass).processRequest();
myActualClass.processRequest();
verify(myActualClass, times(1)).processAnotherRequest(1, "address",
captor.capture());
Assert.assertEquals(1, captor.getValue().getAccess());
}
答案2
得分: 0
首先,除非您不使用powermock,否则无法对静态方法进行模拟。相反,您可以将User对象作为参数传递给processRequest。
public void processRequest(User curUser) {
processAnotherRequest(1, "address", curUser);
}
public void processAnotherRequest(int userId, String address, User user) {
//...
}
然后,您可以在测试代码中使用对象引用。
User adminUser = MyUtils.getUserFromOtherPlace(UserType.ADMIN);
adminUser.setAccess(1);
doCallRealMethod().when(myActualClass).processRequest(adminUser);
myActualClass.processRequest(adminUser);
verify(myActualClass).processAnotherRequest(1, "address", adminUser);
英文:
First of all, you cannot mock a static method unless you don't use powermock. Instead, you can pass User object as a parameter to processRequest.
public void processRequest(User curUser) {
processAnotherRequest(1, "address", curUser);
}
public void processAnotherRequest(int userId, String address, User user) {
//...
}
Then, you can use the object reference in the test code.
User adminUser = MyUtils.getUserFromOtherPlace(UserType.ADMIN);
adminUser.setAccess(1);
doCallRealMethod().when(myActualClass).processRequest(adminUser);
myActualClass.processRequest(adminUser);
verify(myActualClass).processAnotherRequest(1, "address", adminUser);
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论