2017-02-17 247 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,這是不可能回答爲什麼不按預期工作。一旦添加了所需的信息,我可以再看看。