Java Mockito-使用引用类型参数调用验证方法
当我验证某个方法是否应该使用特定参数调用时,我还不熟悉使用Mockito,而所有值类型参数(int、String、enum等)都可以验证,但引用/类类型参数似乎不是,下面是一个示例Java Mockito-使用引用类型参数调用验证方法,java,unit-testing,nullpointerexception,mockito,reference-type,Java,Unit Testing,Nullpointerexception,Mockito,Reference Type,当我验证某个方法是否应该使用特定参数调用时,我还不熟悉使用Mockito,而所有值类型参数(int、String、enum等)都可以验证,但引用/类类型参数似乎不是,下面是一个示例 // my actual class public class MyActualClass { public void processRequest() { User curUser = MyUtils.getUserFromOtherPlace(UserType.ADMIN); p
// 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);
}
}
我知道这可能是因为在我的测试方法中设置的adminUser
不是通过我的实际方法getUserFromOtherPlace->MyUtils.getUserFromOtherPlace生成的同一个引用对象,我还尝试用静态方法模拟返回对象,如
// 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"
那么,我如何将引用对象传递到我的entry方法中,并将其模拟为我的内部方法的返回值呢?顺便说一句,如果我的方法只包含值类型参数,它将工作…首先,除非不使用powermock,否则不能模拟静态方法。相反,您可以将用户对象作为参数传递给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);
因此,为了模拟静态方法,您需要:
@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);
}
但如果有其他选项,我总是不喜欢模拟静态类,所以您可以尝试使用参数捕获器:
//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());
}
//测试类
@俘虏
私家侦探;
//你的测试
@试验
public void testIfMethodBeingCalledCorrectly()方法{
doCallRealMethod().when(myActualClass.processRequest();
myActualClass.processRequest();
验证(myActualClass,次(1)).processAnotherRequest(1,“地址”,
captor.capture());
Assert.assertEquals(1,captor.getValue().getAccess());
}
好吧,我无法更改我的测试方法的签名,但我可以将我的静态类和方法替换为非静态的,在我的测试方法中,创建MyUtils类的新实例,但是,这并不能解决我的问题,因为在测试方法中启动的类实例MyUtils与我在测试类中用于模拟返回对象的实例不同