Сомнения в модульном тестировании DAO
Я ищу информацию для создания модульного теста для типичных методов DAO (поиск пользователя по имени пользователя и т. Д.), И я нашел несколько примеров, использующих такие макеты: http://www.christophbrill.de/de_DE/unit-testing-with-junit-and-mockito/
@Test
public void testComeGetSome() {
// Mock the EntityManager to return our dummy element
Some dummy = new Some();
EntityManager em = Mockito.mock(EntityManager.class);
Mockito.when(em.find(Some.class, 1234)).thenReturn(dummy);
// Mock the SomeDao to use our EntityManager
SomeDao someDao = Mockito.mock(SomeDao.class);
Mockito.when(someDao.comeGetSome(1234)).thenCallRealMethod();
Mockito.when(someDao.getEntityManager()).thenReturn(em);
// Perform the actual test
Assert.assertSame(dummy, someDao.comeGetSome(1234));
Assert.assertNull(someDao.comeGetSome(4321));
}
В книге Лассе Коскела есть аналогичная книга, в которой вместо "Мокито" используется EasyMock.
Дело в том, что мы действительно тестируем в этих примерах? В основном мы через макеты сообщаем, какой объект должен возвращать запрос, а затем утверждаем, что на самом деле он возвратил объект, который мы сказали ему вернуть.
Мы не проверяем, является ли запрос правильным или возвращает ли он другой объект или вообще не содержит объектов (или даже более одного объекта). Мы не можем проверить, возвращает ли он ноль, если объект не существует в базе данных. Эта линия
Assert.assertNull(someDao.comeGetSome(4321));
работает, потому что для этого аргумента нет сценариев, а не потому, что объект не существует.
Похоже, мы просто тестируем, вызывает ли метод правильные методы и объекты (em.find).
Какой смысл в этом модульном тестировании? Есть ли в Java хорошие фреймворки для быстрой настройки базы данных в памяти и выполнения с ней тестов?
2 ответа
Ваши сомнения действительно имеют смысл. На самом деле в большинстве случаев нет необходимости тестировать DAO с помощью модульных тестов, потому что модульные тесты работают с одним уровнем, но DAO взаимодействует с уровнем базы данных.
Эта статья объясняет эту идею: http://www.petrikainulainen.net/programming/testing/writing-tests-for-data-access-code-unit-tests-are-waste/
Следовательно, мы должны проверить DAO и уровень базы данных с интеграционными тестами. Интеграционные тесты учитывают как DAO, так и уровень базы данных.
Эта статья предоставит вам пример Spring + Hibernate: https://dzone.com/articles/easy-integration-testing
Это больше похоже на служебные тесты, чем на настоящие тесты DAO. Например, я использую dbunit
чтобы проверить мой слой DAO.
Например, у меня есть Author
таблица с 2 полями: id
а также name
, Я создаю XML-файл набора данных, как
<?xml version="1.0" encoding="UTF-8"?>
<dataset>
<AUTHOR AUTHOR_ID="1" NAME="FirstAuthor"/>
...
<AUTHOR AUTHOR_ID="10" NAME="TenthAuthor"/>
</dataset>
А потом в моем тестовом классе с помощью Mockito
Я тестирую свои методы DAO, такие как
@Test
@DatabaseSetup(value = "/dao/author/author-data.xml")
public void testFindAll() {
List<Author> authorList = this.authorDAO.findAll();
assertEquals(10, authorList.size());
}