Запуск MongoDB с Maven

Я использую драйвер Java MongoDB для выполнения некоторой настойчивости в своем приложении. Сборка для моего приложения управляется через Maven, и я ищу лучший способ интегрировать ряд модульных тестов, связанных с MongoDB, в мой процесс сборки Maven. Я не могу предположить, что пользователь, создавший приложение, установил dameon MongoDB в качестве службы и, следовательно, должен запустить демон до выполнения соответствующих модульных тестов.

Моя первая мысль заключалась в том, чтобы сохранить двоичные файлы в папке ресурсов тестового каталога (например, src/test/resources) и запустить демон с помощью Runtime.exec(). Есть ли подход, который является более чистым? Я чувствую, что Runtime.exec() - быстрый и грязный способ получить что-то работающее, но не самое идеальное... Мне нужно это, чтобы работать как с linux, так и с окнами.

Ответ 1

Я создал плагин Maven, который обертывает flapdoodle.de 'embedded mongo' API:

embedmongo-maven-plugin

Он обеспечивает цель start, которую вы можете использовать, чтобы запустить любую версию MongoDB, которую вы хотите (например, во время pre-integration-test), и цель stop, которая остановит MongoDB (например, во время post-integration-test).

Бинарные файлы MongoDB загружаются и сохраняются в ~/.embedmongo для будущих сборок.

Ответ 2

У моей команды была такая же проблема, но мы не смогли найти какой-либо чистый способ ее решения. Мы даже пошли по плохому пути использования плагина ant -run для выполнения некоторых Ant задач (независимо от ОС), которые при необходимости запустили демон MongoDB. Мы закончили тем, что отказались от всего этого в классе AbstractMongoDbTest, который в нем @Before, утверждает, что MongoDB запущен, а если нет, не удается выполнить тест с очень конкретным сообщением, в котором пользователь должен начать Mongo. Это не идеально, но, к сожалению, если вы вводите внешнюю зависимость от своих модульных тестов, они больше не являются модульными тестами, они являются интеграционными тестами, и небезосновательно требовать от людей наличия зависимостей.

Другие параметры:

Если все разработчики находятся в одной и той же сети, вы можете настроить выделенный экземпляр MongoDB на сервере и проверить, все тесты указывают на это имя хоста вместо localhost (по умолчанию).

Вы также можете абстрагировать все взаимодействия с MongoDB за интерфейсами с шаблонами репозитория с реализациями MongoDB. Это, вероятно, хорошая идея. Это позволит вашим тестам либо издеваться над интерфейсами репо или создавать заглушки служб. Это позволит тестировать модульные тесты. Это также имеет преимущество, если вы когда-нибудь решите отойти от MongoDB до, возможно, CouchDB или даже реляционной базы данных, такой как Oracle, ваши тесты не нужно менять, вам просто нужно создать новые реализации ваших интерфейсов репо.

Ответ 3

Хотя @joelittlejohn ответ на использование плагина embedmongo будет работать. Вы можете использовать его непосредственно в своих модульных тестах, чтобы провести небольшие контролируемые тесты.

public class MongoDbTest {
    private static MongodForTestsFactory testsFactory;

    @BeforeClass
    public static void setMongoDB() throws IOException {
        testsFactory = MongodForTestsFactory.with(Version.Main.PRODUCTION);
    }

    @AfterClass
    public static void tearDownMongoDB() throws Exception {
        testsFactory.shutdown();
    }

    private DB db;

    @Before
    public void setUpMongoDB() throws Exception {
        final Mongo mongo = testsFactory.newMongo();
        db = testsFactory.newDB(mongo);
    }

    @Test
    public void testDatabaseCreated() {
        assertNotNull(db);
    }
}

Я действительно документировал полное объяснение этого здесь (это будет слишком многословно, чтобы поместить его в stackoverflow): http://www.trajano.net/2012/06/mongodb-with-maven/