2017-02-17 84 views
2

我对Mocking没有多少经验,我最近开始在我的Junit测试用例中使用它。但是,我很难理解执行。Powermockito:java.lang.IllegalArgumentException:参数类型不匹配

我得到抛出:IllegalArgumentException当我尝试这个代码

PowerMockito.doNothing().when(spyObject, "lockUser", String.class, User.class); 

但是,当我提供了LOCKUSER会收到在执行时的值,一切正常。

工作代码

PowerMockito.doNothing().when(spyObject, "lockUser", "my_text", userMock); 

我搞糊涂了这种行为。我期待着相同的行为。 有人可以解释为什么会发生这种情况吗?

此外,当我有以下代码

PowerMockito.doNothing().when(spyObject, "lockUser", anyString(), anyObject()); 

的方法不再嘲笑和被调用真正的方法。

有趣的是,我有另一个同名的方法“lockUser”,它具有不同数量的参数。在我的其他测试方法中,我只使用了Matchers(anyObject(),anyString()等),并且按照预期工作。

PowerMockito.doNothing().when(spyObject, "lockUser", anyObject(), anyString(), anyString(), anyString()); 

所有lockUser方法都是priavate。

我与1.9.5的Mockito正在与PowerMock一起1.5.6

任何帮助是极大的赞赏

编辑 附加代码,以明确

Class Core { 
public Worker getWorker(String workerId) { 
    // Get worker from Map<String, Worker> fID_WRK with workerId as key 
    // Get user from worker (I have mocked this part, so my mock user is  
    // returned) 
    If(user.isTooOld()) { 
    lockUserAndNotify(reason, user); 
    throw new UserLockedException("Too old"); 
    } 

private void lockUserAndNotify(String reason, User user) { 
    lockUserAndNotify(reason, user.fname, user.lname); // locks user and notifies 
} 

public getUser(String login, String password) { 
    // find user in database 
    if(user password is too old) { 
    lockUserAndNotify(dbConnection, fname, lname, userId); 
    } 
} 

private lockUserAndNotify(Connection dbConn, String fName, String lName, String 
       userId) { 
    //method call to lock the user 
    //method call to notify the admin 
} 


} 

我的测试类

Class CoreTest { 
    @Test (expected = UserLockedException.class) 
    public void getUser_ThrowsException() throws     
      Exception{ 

    Core core = new Core(); 
    Core coreSpy = PowerMockito.spy(core); 

    when(userMock.isPwdUpdateTimeExpired()).thenReturn(true); 
    PowerMockito.doNothing().when(coreSpy, "lockUserAndNotify", 
    anyObject(), anyString(), anyString(), anyString(), anyString()); 

    admin4.UserManager.getUser("l.user1","password"); 

    } 

@Test (expected = UserLockedException.class) 
     public void getWorker_ThrowsException() throws     
       Exception{ 

     Core core = new Core(); 
     Core coreSpy = PowerMockito.spy(core); 

     Map workerMap = Whitebox.getInternalState(coreSpy, "fID_WRK"); 
     Map workerMapSpy = PowerMockito.spy(workerMap); 

     when(workerMapSpy.getWorker("12345")).thenReturn(workerMock); 
     when(workerMock.getUser()).thenReturn(userMock); 
     when(userMock.isTooOld()).thenReturn(true); 
     PowerMockito.doNothing().when(coreSpy, "lockUserAndNotify", 
     anyString(), anyObject()); 

     admin4.UserManager.getWorker("123445"); 

     } 
} 

所以测试getUser_ThrowsEx ception按预期工作,但getWorker_ThrowsException不会。

+0

你介意发布你打算测试的代码吗? –

+0

你的代码在这里不能编译。使其难以复制并帮助您。阅读http://sscce.org/ – nikhil

回答

2

要回答你的问题有关IllegalArgumentException: argument type mismatch的一部分,当您使用

PowerMockito.doNothing().when(spyObject, "lockUser", String.class, User.class); 

PowerMocktioStubber.when文档得到这个,因为你使用正确的API,相关部门在这里重现 -

public static <T> org.mockito.stubbing.OngoingStubbing<T> when(Class<?> klass, 
                   Object... arguments) 
                 throws Exception 

Expect calls to private static methods without having to specify the method name. The method will be looked up using the parameter types if possible 

Throws: 
    Exception - If something unexpected goes wrong. 
See Also: 
    Mockito#when(Object)} 

正如您已经观察到的,您可以使用真实参数的值,也可以使用Matchers,如anyString

下面是一些示例代码,以证明这一点 -

public class Core { 
    public String getWorker(String workerId) { 
     if (workerId.isEmpty()) { 
      lockUser("Reason", workerId); 
     } 
     return workerId; 
    } 

    private void lockUser(String reason, String user) { 
    } 
} 

和相应的测试 -

@RunWith(PowerMockRunner.class) 
@PrepareForTest(Core.class) 
public class CoreTest { 

    @Test 
    // this is incorrect usage and throws an IllegalArgumentException 
    public void test1() throws Exception { 
     Core spy = PowerMockito.spy(new Core()); 
     PowerMockito.doNothing().when(spy, "lockUser", String.class, String.class); 
     spy.getWorker(""); 
    } 

    @Test 
    public void test2() throws Exception { 
     Core spy = PowerMockito.spy(new Core()); 
     PowerMockito.doNothing().when(spy, "lockUser", Mockito.anyString(), Mockito.anyString()); 
     spy.getWorker(""); 
     PowerMockito.verifyPrivate(spy).invoke("lockUser", Mockito.anyString(), Mockito.anyString()); 
    } 

    @Test 
    public void test3() throws Exception { 
     Core spy = PowerMockito.spy(new Core()); 
     PowerMockito.doNothing().when(spy, "lockUser", "abc", "Reason"); 
     spy.getWorker("abc"); 
     PowerMockito.verifyPrivate(spy, Mockito.times(0)).invoke("lockUser", Mockito.anyString(), Mockito.anyString()); 
    } 
} 

没有编译代码或不同之处在于你得到getWorker_ThrowsException,这是不可能回答为什么不按预期工作。一旦添加了所需的信息,我可以再看看。