2017-02-17 12 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.

Я работаю с Mockito 1.9.5 вместе с 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, вы получите это, потому что вы используете API неправильно при использовании

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

Смотрите документацию PowerMocktioStubber.when, соответствующий раздел воспроизведен здесь -

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

Without компилируемый код или исключением того, что вы получите за getWorker_ThrowsException, это не представляется возможным ответить, почему это не работает должным образом. Я могу взглянуть снова, как только вы добавите требуемую информацию.

Смежные вопросы