简体   繁体   English

Java Mockito - 使用引用类型参数调用的验证方法

[英]Java Mockito - verify method called with reference type parameter

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我是使用 Mockito 的新手,而我正在验证应使用特定参数调用某些方法,而所有值类型参数(int、String、enum 等)都可以验证,但引用/类类型参数似乎不是,这里是例子

// 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 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?那么如何将引用 object 传递到我的入口方法中,并在此处将其模拟为我的内部方法的返回值? BTW, if my method only contains value type parameter, it will work...顺便说一句,如果我的方法只包含值类型参数,它将起作用......

So in order to mock you static method you will need to:因此,为了模拟您的 static 方法,您需要:

@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:但是如果有其他选择,我总是不喜欢模拟 static 类,所以也许你可以尝试一个参数捕获器:

//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());
}

First of all, you cannot mock a static method unless you don't use powermock.首先,除非您不使用 powermock,否则您无法模拟 static 方法。 Instead, you can pass User object as a parameter to processRequest.相反,您可以将用户 object 作为参数传递给 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.然后,您可以在测试代码中使用 object 参考。

User adminUser = MyUtils.getUserFromOtherPlace(UserType.ADMIN);
adminUser.setAccess(1);
doCallRealMethod().when(myActualClass).processRequest(adminUser);
myActualClass.processRequest(adminUser);
verify(myActualClass).processAnotherRequest(1, "address", adminUser);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM