2014-02-12 3 views
0

У меня есть этот TestNG код метода испытаний:Получение InvalidUseOfMatchersException когда гася метод

@InjectMocks 
private FilmeService filmeService = new FilmeServiceImpl(); 

@Mock 
private FilmeDAO filmeDao; 

@BeforeMethod(alwaysRun=true) 
public void injectDao() { 
    MockitoAnnotations.initMocks(this); 
} 

//... another tests here 

@Test 
public void getRandomEnqueteFilmes() { 
    @SuppressWarnings("unchecked") 
    List<Filme> listaFilmes = mock(List.class); 

    when(listaFilmes.get(anyInt())).thenReturn(any(Filme.class)); 
    when(filmeDao.listAll()).thenReturn(listaFilmes); 

    List<Filme> filmes = filmeService.getRandomEnqueteFilmes(); 

    assertNotNull(filmes, "Lista de filmes retornou vazia"); 
    assertEquals(filmes.size(), 2, "Lista não retornou com 2 filmes"); 
} 

И я получаю «org.mockito.exceptions.misusing.InvalidUseOfMatchersException: Неправильное использование аргумента matchers 0 matchers ожидается, 1 записано:»в вызове listAll() метод в этом коде:

@Override 
public List<Filme> getRandomEnqueteFilmes() { 
    int indice1, indice2 = 0; 
    List<Filme> filmesExibir = new ArrayList<Filme>(); 
    List<Filme> filmes = dao.listAll(); 

    Random randomGenerator = new Random(); 
    indice1 = randomGenerator.nextInt(5); 
    do { 
     indice2 = randomGenerator.nextInt(5); 
    } while(indice1 == indice2); 

    filmesExibir.add(filmes.get(indice1)); 
    filmesExibir.add(filmes.get(indice2)); 

    return filmesExibir; 
} 

Я Prety уверен, что я что-то здесь отсутствует, но я не знаю, что это такое! Кто-то помогает?

+0

Является ли метод dao.listAll() 'final? Какой тип 'dao'? У вас может быть такая же проблема, как в [этом вопросе] (http://stackoverflow.com/questions/11458963/mockito-0-matchers-expected-1-recorded-invaliduseofmatchersexception). – andersschuller

+0

@andersschuller Нет, dao - это издевательский объект filmeDao, я улучшил свой вопрос, чтобы сделать его более заметным. Я прочитал вопрос, который вы упомянули, но ничего не уточняет ответ на мою проблему. – Iogui

ответ

3
when(listaFilmes.get(anyInt())).thenReturn(any(Filme.class)); 

У вас возникли проблемы. Вы не можете использовать any в возвращаемом значении. any - это Matcher - он используется для сопоставления значений параметров для stubbing и проверки - и не имеет смысла определять возвращаемое значение для вызова. Вам нужно будет явно вернуть экземпляр Filme или оставить его пустым (что является поведением по умолчанию, которое может привести к поражению точки stubbing).

Следует отметить, что часто рекомендуется использовать реальный список вместо списка mock. В отличие от настраиваемого кода, который вы разработали, реализации List хорошо определены и хорошо протестированы, а в отличие от mock Lists реальный список вряд ли сломается, если вы реорганизуете свою тестируемую систему для вызова разных методов. Это вопрос философии стиля и тестирования, но вам может показаться выгодным использовать настоящий список здесь.


Почему это правило является причиной такого исключения? Ну, это объяснение ломает некоторые абстракции Mockito, но matchers don't behave like you think they might-они записывают значение в секретный стек ThreadLocal объектов ArgumentMatcher и возвращают null или какое-либо другое фиктивное значение, а при вызове when или verify Mockito видит непустой стек и знает, чтобы использовать эти Матчи, предпочитая фактические значения аргументов. Насколько Mockito и порядок оценки Java обеспокоены тем, что ваш код выглядит следующим образом:

when(listaFilmes.get(anyInt())).thenReturn(null); 
when(filmeDao.listAll(any())).thenReturn(listaFilmes); // nonsense 

Естественно Mockito видит any Искатель, и listAll не принимает аргумент, так что есть 0 matchers ожидается, 1 записано.

+0

Да, парень! Ты понял! Я знал, что у меня что-то не хватает, и ты только что нашел его. Хотя я не согласен с вами в вопросе «Mock a List», потому что я не хочу тестировать сам List, а другой код, который его использует, и я не хочу кормить этот список. Couse это может стать трудно сделать в тех местах, где список может стать большим по своим размерам. – Iogui

+1

Рад помочь! Что касается списка, это вопрос философии, о котором Мартин Фаулер писал в своей полезной статье [«Mocks Are not Stubs»] (http://martinfowler.com/articles/mocksArentStubs.html#ClassicalAndMockistTesting). (Все это стоит прочитать.) Вы можете продолжать использовать макеты, конечно, разумные люди не согласны здесь, но будьте осторожны, чтобы он мог нарушить ваши тесты, если вы реорганизуете свой код, чтобы использовать разные методы List, и всегда хорошо помнить у вас есть альтернативы (Stubs, Fakes и real objects) в качестве параметров здесь. Ура! –

+0

+1 ссылка на статью Фаулера. Очень полезно. – Iogui

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