Групповое тестирование с помощью MongoDB - программирование
Подтвердить что ты не робот

Групповое тестирование с помощью MongoDB

Моя база данных по выбору - MongoDB. Я пишу API уровня данных для абстрактной детали реализации из клиентских приложений, то есть я по существу предоставляет единый открытый интерфейс (объект, который действует как IDL).

Я тестирую свою логику, когда я вхожу в TDD. Перед каждым unit test вызывается метод @Before для создания одноэлементной базы данных, после чего, когда тест завершается, вызывается метод @After для удаления базы данных. Это помогает повысить независимость от единичных тестов.

Почти во всех модульных тестах, то есть при выполнении контекстного запроса, требуется какая-то логика вставки, которая должна произойти перед рукой. Мой открытый интерфейс предоставляет метод вставки - однако представляется неправильным использовать этот метод в качестве логики предшественника для каждого unit test.

На самом деле мне нужен какой-то насмешливый механизм, но у меня не было много опыта в насмешливых фреймворках, и кажется, что Google не возвращает ничего из насмешливого фрейма, который можно использовать с MongoDB.

Что делают другие в этих ситуациях? То есть, как люди unit test код, который взаимодействует с базой данных?

Кроме того, мой открытый интерфейс подключается к базе данных, определенной во внешнем файле конфигурации - кажется неправильным использовать это соединение для моего модульного тестирования - опять-таки ситуация, которая выиграет от какого-то насмешки?

4b9b3361

Ответ 1

Технически тесты, которые говорят с базой данных (nosql или иначе), не являются модульными тестами, так как тесты тестируют взаимодействия с внешней системой, а не просто тестирование изолированной единицы кода. Однако тесты, которые говорят с базой данных, часто чрезвычайно полезны и часто бывают достаточно быстрыми, чтобы работать с другими модульными тестами.

Обычно у меня есть интерфейс службы (например, UserService), который инкапсулирует всю логику работы с базой данных. Код, который использует UserService, может использовать измененную версию UserService и легко протестирован.

При тестировании реализации Службы, которая ведет переговоры с Mongo (например, MongoUserService), проще всего написать некоторый Java-код, который запустит/остановит процесс mongo на локальной машине и подключит ваш MongoUserService к этому, см. это вопрос для некоторых заметок.

Вы можете попытаться издеваться над функциональностью базы данных при тестировании MongoUserService, но, как правило, это слишком подвержено ошибкам и не тестирует то, что вы действительно хотите протестировать, а это взаимодействие с реальной базой данных. Поэтому при написании тестов для MongoUserService вы настраиваете состояние базы данных для каждого теста. Посмотрите DbUnit на пример структуры для этого с базой данных.

Ответ 2

Как писали в этом сообщении sbridges, это плохая идея не иметь выделенный сервис (иногда также известный как репозиторий или DAO), который абстрагирует доступ к данным из логики. Затем вы можете проверить логику, предоставив макет DAO.

Другой подход, который я делаю, - создать Mock объекта Mongo (например, PowerMockito), а затем вернуть соответствующие результаты. Это потому, что вам не нужно проверять, работает ли база данных в модульных тестах, но более подробно вам следует проверить, был ли правильный запрос отправлен в базу данных.

Mongo mongo = PowerMockito.mock(Mongo.class);
DB db = PowerMockito.mock(DB.class);
DBCollection dbCollection = PowerMockito.mock(DBCollection.class);

PowerMockito.when(mongo.getDB("foo")).thenReturn(db);
PowerMockito.when(db.getCollection("bar")).thenReturn(dbCollection);

MyService svc = new MyService(mongo); // Use some kind of dependency injection
svc.getObjectById(1);

PowerMockito.verify(dbCollection).findOne(new BasicDBObject("_id", 1));

Это тоже будет вариант. Конечно, создание mocks и возврат соответствующих объектов просто закодировано в качестве примера выше.

Ответ 3

Я написал реализацию stub MongoDB в Java: mongo-java-server

По умолчанию используется внутренняя память, которая может быть легко использована в тестах Unit и Integration.

Пример

MongoServer server = new MongoServer(new MemoryBackend());
// bind on a random local port
InetSocketAddress serverAddress = server.bind();

MongoClient client = new MongoClient(new ServerAddress(serverAddress));

DBCollection coll = client.getDB("testdb").getCollection("testcoll");
// creates the database and collection in memory and inserts the object
coll.insert(new BasicDBObject("key", "value"));

assertEquals(1, collection.count());
assertEquals("value", collection.findOne().get("key"));

client.close();
server.shutdownNow();