Что не так с частичной насмешкой в этом случае?
Допустим, у меня есть два метода, один из которых, по сути, является оберткой для другого метода с небольшим количеством дополнительной обработки:
public class ItemRepositoryImpl implements ItemRepository {
...
@Override
public void delete(UUID itemID) {
Item item = findOne(itemID);
delete(item);
}
@Override
public void delete(Item item) {
// Do a bunch of stuff that needs a lot of tests run on it, like
// deleting from multiple data sources etc
...
}
}
Что плохого в написании модульного теста для метода удаления (UUID), который частично выполняет макет ItemRepositoryImpl и проверяет, что удаление (UUID) в конечном итоге вызывает удаление (Item)? Если бы я сделал это, мне бы не пришлось писать кучу дублирующих тестов для каждого метода удаления!
В Mockito я мог бы реализовать такой тест с помощью шпиона:
ItemRepository spyRepo = spy(repository); // Create the spy
when(spyRepo.findOne(itemID)).thenReturn(item); // Stub the findOne method
doNothing().when(spyRepo).delete(item); // Stub the delete(Item) method
spyRepo.delete(itemID); // Call the method under test
// Verify that the delete(Item) method was called
verify(spyRepo).delete(item);
Тем не менее, документация Mockito категорически не рекомендует использовать этот тип частичного макета, в основном заявляя, что он должен использоваться только во временном унаследованном коде и сторонних API. Что будет лучшим решением?
1 ответ
Если вы проводите чистый юнит-тест, а ваша юнит-тест - это метод, я бы сказал, что в том, что вы здесь высмеяли, нет ничего плохого. Некоторые утверждают, что модульные тесты должны использовать более "черный ящик", и что путем имитации вызовов методов ваш тест слишком много знает о реализации тестируемого метода.
Если тестируемый вами модуль является классом, а не методом, то вы можете просто высмеивать вызовы других классов.
Всегда есть споры вокруг юнит-тестов. Вот интересная статья на эту тему, которая очень актуальна для вашего вопроса: http://martinfowler.com/articles/mocksArentStubs.html