2012-04-26 2 views
6

Я хочу использовать два пользовательских совпадения для одного метода. В принципе, если я передаю метод VALUE_A, я хочу, чтобы он возвращал RESULT_A, и если я передаю его VALUE_B, я хочу, чтобы он возвращал RESULT_B. Так вот фрагмент коды:Mockito действует странно, когда я назначаю несколько пользовательских совпадений для одного метода

class IsNonEmpty extends ArgumentMatcher<Get> { 
    public boolean matches(Object get) { 
     //For some reason, this method is called when I assign the IsEmpty matcher to MockHtable.get() 
     //When this happens, the value of the get argument is null, so this method throws an NPE 

     return Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key)); 
    } 
} 

class IsEmpty extends ArgumentMatcher<Get> { 
    public boolean matches(Object get) { 
     return !(Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key))); 
    } 
}  

[...] 

//This line executes just fine 
Mockito.when(mockHTable.get(Mockito.argThat(new IsNonEmpty()))).thenReturn(dbResult); 

[...] 

//This line calls IsNonEmpty.matches() for some reason. IsNonEmpty.matches() throws an NPE 
Mockito.when(mockHTable.get(Mockito.argThat(new IsEmpty()))).thenReturn(emptyResult); 

Когда я назначить IsEmpty пользовательского Искатель к методу mockHTable.get(), это вызывает IsNonEmpty.matches функции(). Не знаю, почему это делается. Поэтому я перехожу к классу IsNonEmpty:

class IsNonEmpty extends ArgumentMatcher<Get> { 
    public boolean matches(Object get) { 
     //For some reason, this method is called when I assign the IsEmpty matcher. Weird, no? 
     if(get == null) { 
      return false; 
     } 

     return Arrays.equals(((Get) get).getRow(), SERIALIZATION_HELPER.getValidBytes(key)); 
    } 
} 

а потом все работает просто отлично! IsNonEmpty.matches() все еще вызывается, когда я назначаю элемент IsEmpty для функции mockHTable.get(), но мои ответчики работают точно так, как должны.

Итак, в чем заключена сделка? Почему это происходит? Является ли мой рабочий подход адекватным способом компенсировать это причудливое поведение, или я делаю это неправильно?

ответ

11

Причина, по которой IsNonEmpty.matches() вызывается во второй строке обрыва, заключается в том, что Mockito.argThat(new IsEmpty()) возвращает значение null, которое затем передается в mockHTable.get(). Этот вызов должен быть проверен на более раннем этапе, чтобы убедиться, что это совпадение; и это означает вызов IsNonEmpty.matches().

Я не уверен, почему это делает ваш тест неудачным - это трудно сказать, не видя всего кода.

Но я бы рекомендовал использовать doReturn...when вместо when...thenReturn всякий раз, когда вы должны заглушить один и тот же макет несколько раз. Если вы это сделаете, вы не столкнетесь с такими проблемами. На самом деле, я предпочитаю использовать doReturn...when, предпочтительно when...thenReturn (и аналогично doThrow и doAnswer), хотя большинство людей предпочитает when...thenReturn.

Повторная запись одной из ваших стробирующих линий с синтаксисом doReturn...when выглядит следующим образом. Другой подобен.

Mockito.doReturn(dbResult).when(mockHTable).get(Mockito.argThat(new IsNonEmpty())); 

И наконец, просьба от имени команды разработчиков Mockito (из которых я являюсь участником). Если вы считаете, что это ошибка в Mockito здесь - и из вашего описания, я думаю, что вполне может быть - пожалуйста, ЯВНО

  • отправить сообщение на почтовые группы Mockito ([email protected]) ИЛИ
  • поднимите проблему в списке выпусков Mockito (http://code.google.com/p/mockito/issues/list).

Полезно команде Mockito, если вы действительно можете опубликовать полный пример, а не только то, что, по вашему мнению, являются ключевыми строками - иногда причиной проблемы с Mockito является совершенно неожиданное место.

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

  • Нет связанных вопросов^_^