2017-02-22 14 views
1

Я прочитал довольно много статей/вопросов блога/StackOverflow, но путаница в отношении Mockito mock и spy все еще остается. Итак, я начал использовать их в небольшом Spring Boot приложении. Мое приложение имеет ProductRepository, распространяющееся на CrudRepository.Mockito Mock and Spy в приложении SpringBoot

В настоящее время я тестирую репозиторий насмехаясь над ProductRepository следующим

@RunWith(SpringRunner.class) 
    @SpringBootTest(classes = {RepositoryConfiguration.class}) 
    public class ProductRepositoryMockTest { 

    @Mock 
    private ProductRepository productRepository; 
    @Mock 
    private Product product; 

    @Test 
    public void testMockCreation(){ 
     assertNotNull(product); 
     assertNotNull(productRepository); 
    } 

    @Test 
    public void testSaveProduct() { 
     assertThat(product.getId(), is(equalTo(0))); 
     when(productRepository.save(product)).thenReturn(product); 
     productRepository.save(product); 
     //Obviously this will fail as product is not saved to db and hence 
     //@GeneratedValue won't come to play 
     //assertThat(product.getId() , is(not(0))); 
    } 

    @Test 
    public void testFindProductById() { 

     when(productRepository.findOne(product.getId())).thenReturn(product); 
     assertNotNull(productRepository.findOne(product.getId())); 
     assertEquals(product, productRepository.findOne(product.getId())); 
    } 
    } 

тест проходит. Правильно ли это? Я также хочу понять, как использовать @Spy здесь и зачем мне это нужно? Любые конкретные сценарии, связанные с этим, приветствуются.

Заранее спасибо.

+1

Dont unit test your repositories .. сосредоточиться на сервисном уровне, касающемся модульного тестирования. Если у вас есть логика внутри вашего репозитория, то это, вероятно, недостаток дизайна. –

+0

Да, понял. Благодарю. – user2693135

+0

@Maciej Kowalski Наконец удалось использовать mocks и шпионов на основе ваших входов для тестирования уровня сервиса. Но не знаю, правильно ли я сделал это. Мой репо находится в https://github.com/ximanta/mockito_spy_example. Ваши наблюдения будут ценными. Если необходимо, можете опубликовать это как вопрос. Благодарю. – user2693135

ответ

2

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

1) Hamcrest - Если это возможно, я настоятельно рекомендую использовать Hamcrest для ваших утвержденных реализаций. Прежде всего, он гораздо более универсален и богат, чем стандартные утверждения junit. Во-вторых, вы, возможно, когда-нибудь захотите (как я сделал на одном из моих проектов) переключиться с junit на testng для справки. Имея все ваши утверждения, основанные на реалистичной реализации xunit, коммутатор не будет настолько болезненным.

2) Утверждения - вместо assertNull, assertEquals идти на Hamcrest в assertThat(String description, T value, Mathcer<T> matcher); Благодаря тому, что вы получите четкие сообщения об ошибках, когда тест-брейков.

3) Небольшие тесты - В вашем тестовом репозитории не помещайте все случаи в одном тесте. Попробуйте создать множество небольших и простых тестов для таких случаев, как findOne .. count .. findAll и т. Д. Снова будет легче найти проблему, когда пройдёт небольшой тест. А если больше случаев придут вам не в конечном итоге с более чем 200 линий теста, который является неприемлемым

4) Именование - Не называйте свои тесты, как .. testXYZ. Очевидно, что это методы испытаний. Я бы рекомендовал использовать BDD способ именования: shouldX_whenY_givenZ. F.e. shouldReturnZeroCount_givenNoEntitiesInTheDatabase

5) Структура - Попробуйте разделить каждый из вашей реализации теста в трех явных разделах, в том числе комментариев для наилучшего результата:

public void should..() throws Exception{ 
     // Arrange 

      // when().then() 
      // mock() 

     // Act 

      // classUnderTest.process() 

     // Assert 

      // assertThat(..) 
    } 

6) Не расщепляется ваших тестовых классов между Мок/Шпионский тест. HAve один ImplTest.

7) Никогда не издевайтесь над классом, который вы тестируете. В худшем случае используйте Spy, если вам нужно высмеять некоторые из методов тестируемого класса. Точка насмешивания заключается в том, чтобы изолировать реализацию в тестируемом классе, так что во время теста вызывается только эта логика классов. Макет только зависимостей класса.

+0

Спасибо. Теперь все ясно. – user2693135

+0

Любые мысли о том, почему аннотация InjectMock обескуражена по сравнению с инициализацией тестируемого объекта с помощью mocks с использованием метода конструктора/сеттера? – user2693135

+0

его фактически поощряли. Делает тестовый код более четким –

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