2013-12-06 3 views
1

Я пытаюсь издеваться следующим метод:Борясь с модульным тестированием и насмешливым

public void add(Question question) { 
     String username = authenticationManager.getUsername(); 
     Candidate candidate = userService.getByUsername(username); 

     if (!authenticationManager.hasPermission("ROLE_ADMIN")) { 
      question.setStatus(QuestionStatus.WAITING); 
     } 

     question.setCandidate(candidate); 
     questionRepository.add(question); 
    } 

Это моя попытка:

@Test 
public void add_savesQuestionWithStatusWaiting_whenSubmittedAsUser() { 
    Candidate candidate = new Candidate(); 
    Question question = mock(Question.class); 

    when(authenticationManager.getUsername()).thenReturn("andreas"); 
    when(userService.getByUsername("andreas")).thenReturn(candidate); 
    when(authenticationManager.hasPermission("ROLE_ADMIN")).thenReturn(true); 

    questionService.add(question); 
    verify(question, times(0)).setStatus(any(QuestionStatus.class)); 
} 

, что я пытаюсь сделать, это проверить логику приложения. Когда пользователь не имеет ROLE_ADMIN, статус вопроса будет установлен в ожидании. Я делаю насмешливое право?

+0

Каков ваш результат теста? – Luke

+0

@ Luke Я ищу ответ, говорящий, что это правильный способ сделать это или неправильный способ сделать это. Я не уверен, правильно понял. Тест проходит, хотя. – LuckyLuke

+0

вы также можете подтвердить (вопрос) .setCandidate (кандидат); verifyNoMoreInteractions (вопрос); – hoaz

ответ

0

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

Итак, с точки зрения использования вами mockito вы делаете довольно хорошо. Что не совсем в том, что questionService.add слишком много делает. 'add' предполагает, что он помещает некоторый объект в контейнер и ничего другого. Вместо этого он также выполняет сложную настройку объекта вопроса. Другими словами, он имеет побочные эффекты. В результате количество различных граничных условий, которые вы должны испытывать, велико. Это затруднит ваши испытания в будущем. Посмотрите, сколько издевок вы должны были создать.

Если вы вернетесь к своему тесту через некоторое время, и вы попытаетесь выяснить, что он делает, это будет просто? Я также считаю, что тестовое имя не отражает то, что на самом деле проверено. Для меня «add_savesQuestionWithStatusWaiting_whenSubmittedAsUser» подразумевает, что я должен ожидать, что в конце вопрос должен быть сохранен со статусом, установленным на «ожидание», вместо этого вы используете проверку, чтобы проверить, не было ли вызова setStatus().

Я бы попытался реорганизовать код метода добавления, поэтому все, что он делает, это вставка элемента в queryService. Затем я проверил бы различные граничные условия для questionService (например, как он будет вести себя, когда будет предоставлен нуль). Я также переместил бы настройку вопроса на другой уровень вашего приложения и проверил бы его в другом блоке.

+0

Вопрос-служба add-method - это компонент в моем сервисном слое. Я не понимаю, как я перемещаю любую из этих логик в другое место? – LuckyLuke

+0

Прочитав ответ пару раз, и я читал/работал над некоторым кодом, я понимаю, что вы имеете в виду. – LuckyLuke

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