Мой вопрос - это вариант этого.
Поскольку для моего проекта Java Web-app требуется много фильтров/запросов и интерфейсов чтения с такими инструментами, как GridFS, я изо всех сил пытаюсь придумать разумный способ использования MongoDB в том, как это предлагает предлагаемое решение.
Поэтому я рассматриваю возможность запуска встроенного экземпляра MongoDB вместе с моими интеграционными тестами. Я бы хотел, чтобы автоматически запускался (либо для каждого теста, либо для всего пакета), очистить базу данных для каждого теста и закрыть > в конце. Эти тесты могут выполняться на машинах разработки, а также на сервере CI, поэтому мое решение также должно быть переносимым.
Может ли кто-нибудь, у кого больше знаний о MongoDB, помочь мне понять идею осуществимости этого подхода и/или, возможно, предложить любые материалы для чтения, которые могут помочь мне начать работу?
Я также открыт для других предложений, которые могут возникнуть у людей о том, как я мог бы подойти к этой проблеме...
Я нашел Embedded MongoDB библиотеку, которая выглядит довольно многообещающей и делает то, о чем вы просили.
В настоящее время поддерживаются версии MongoDB: 1.6.5
до 3.1.6
, если двоичные файлы все еще доступны из настроенного зеркала.
Вот краткий пример использования, который я только что пробовал, и он отлично работает:
public class EmbeddedMongoTest {
private static final String DATABASE_NAME = "embedded";
private MongodExecutable mongodExe;
private MongodProcess mongod;
private Mongo mongo;
@Before
public void beforeEach() throws Exception {
MongoDBRuntime runtime = MongoDBRuntime.getDefaultInstance();
mongodExe = runtime.prepare(new MongodConfig(Version.V2_3_0, 12345, Network.localhostIsIPv6()));
mongod = mongodExe.start();
mongo = new Mongo("localhost", 12345);
}
@After
public void afterEach() throws Exception {
if (this.mongod != null) {
this.mongod.stop();
this.mongodExe.stop();
}
}
@Test
public void shouldCreateNewObjectInEmbeddedMongoDb() {
// given
DB db = mongo.getDB(DATABASE_NAME);
DBCollection col = db.createCollection("testCollection", new BasicDBObject());
// when
col.save(new BasicDBObject("testDoc", new Date()));
// then
assertThat(col.getCount(), Matchers.is(1L));
}
}
Существует продукт Foursquare Fongo. Fongo - это встроенная в Java реализация mongo. Он перехватывает вызовы стандартного mongo-java-драйвера для находок, обновлений, вставок, удалений и других методов. Основное использование - для легкого модульного тестирования, где вы не хотите разворачивать процесс mongo.
Если вы используете sbt и specs2, я написал такую же оболочку для embedmongo
Если вы используете Maven, вам может быть интересен плагин, который я создал, который обертывает flapdoodle.de 'встроенный mongo' API:
Он обеспечивает цель start
, которую вы можете использовать, чтобы запустить любую версию MongoDB, которую вы хотите (например, во время pre-integration-test
), и цель stop
, которая остановит MongoDB (например, во время post-integration-test
).
Настоящая выгода от использования этого плагина над другими заключается в том, что MongoDB не требуется устанавливать заранее. Бинарные файлы MongoDB загружаются и сохраняются в ~/.embedmongo
для будущих сборок.
с spring -boot 1.3 вы можете использовать EmbeddedMongoAutoConfiguration
pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.3.2.RELEASE</version>
</parent>
...
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>${embedded-mongo.version}</version>
</dependency>
MongoConfig
@Configuration
@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class })
public class MongoConfig{
}
Вы можете запустить MongoDB в памяти с версии 3.2.6. На сайт:
Начиная с версии MongoDB Enterprise 3.2.6, память в памяти двигатель является частью общей доступности (GA) в 64-битных сборках. Помимо некоторых метаданных и диагностических данных, память в памяти двигатель не поддерживает данные на диске, включая конфигурацию данные, индексы, учетные данные пользователя и т.д.
Не только для модульных тестов, но и прочитайте этот пост в блоге, если вы хотите запустить MongoDB (даже кластер) в качестве развертывания в памяти, если вы используете Linux.
http://edgystuff.tumblr.com/post/49304254688
Было бы здорово, если бы он был из коробки, как RavenDB.
Вы также можете проверить этот проект, который имитирует MongoDB внутри JVM-памяти. https://github.com/thiloplanz/jmockmongo Но он все еще находится в разработке.
Если вы используете maven, вы можете использовать наш http://mvnrepository.com/artifact/com.wenzani/mongodb-maven-plugin
Как и в упомянутом здесь встраиваемом plugmongo-maven-плагине, есть также Gradle Монгонский плагин доступно.
Как и плагин Maven, он также обертывает flapdoodle EmbeddedMongoDb api и позволяет запускать управляемый экземпляр Mongo из ваши сборки Gradle.
Здесь обновленная (для 2019 года) версия принятого ответа от @rozky (многое изменилось в библиотеках Mongo и Embedded MongoDB).
package com.example.mongo;
import com.mongodb.BasicDBObject;
import com.mongodb.MongoClient;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoDatabase;
import de.flapdoodle.embed.mongo.MongodExecutable;
import de.flapdoodle.embed.mongo.MongodProcess;
import de.flapdoodle.embed.mongo.MongodStarter;
import de.flapdoodle.embed.mongo.config.IMongodConfig;
import de.flapdoodle.embed.mongo.config.MongodConfigBuilder;
import de.flapdoodle.embed.mongo.config.Net;
import de.flapdoodle.embed.mongo.distribution.Version;
import de.flapdoodle.embed.process.runtime.Network;
import java.util.Date;
import org.junit.After;
import static org.junit.Assert.*;
import org.junit.Before;
import org.junit.Test;
public class EmbeddedMongoTest
{
private static final String DATABASE_NAME = "embedded";
private MongodExecutable mongodExe;
private MongodProcess mongod;
private MongoClient mongo;
@Before
public void beforeEach() throws Exception {
MongodStarter starter = MongodStarter.getDefaultInstance();
String bindIp = "localhost";
int port = 12345;
IMongodConfig mongodConfig = new MongodConfigBuilder()
.version(Version.Main.PRODUCTION)
.net(new Net(bindIp, port, Network.localhostIsIPv6()))
.build();
this.mongodExe = starter.prepare(mongodConfig);
this.mongod = mongodExe.start();
this.mongo = new MongoClient(bindIp, port);
}
@After
public void afterEach() throws Exception {
if (this.mongod != null) {
this.mongod.stop();
this.mongodExe.stop();
}
}
@Test
public void shouldCreateNewObjectInEmbeddedMongoDb() {
// given
MongoDatabase db = mongo.getDatabase(DATABASE_NAME);
db.createCollection("testCollection");
MongoCollection<BasicDBObject> col = db.getCollection("testCollection", BasicDBObject.class);
// when
col.insertOne(new BasicDBObject("testDoc", new Date()));
// then
assertEquals(1L, col.countDocuments());
}
}
Проверьте этот пример кода здесь: https://github.com/familysyan/embedded-mongo-integ. Нет установки, никакой зависимости. Это просто независимая от платформы ant script, которая загружает и настраивает для вас. Он также очищает все после ваших тестов.
В процессе производства вы будете использовать реальную базу данных.
Если вы хотите, чтобы ваши тесты отображали, как ваш продукт ведет себя на производстве, используйте реальный экземпляр Mongo.
Поддельная реализация может не соответствовать точно такой же, как реальная. При тестировании вы должны стремиться к правильности. Скорость выполнения занимает второе место.