Как настроить встроенную MongoDB с аутентификацией для использования в интеграционных тестах весенней загрузки?

У меня есть приложение весенней загрузки, которое использует MongoDB для сохранения. Я собираю интеграционные тесты и использую встраиваемый mongo для flapdoodle библиотека для встроенной БД.

Это в сочетании с автоматической настройкой загрузки Spring, и все прекрасно работает для интеграционных тестов. Однако как только я добавляю учетные данные для аутентификации для MongoDB, все разваливается.

Насколько я понимаю, автоматическая настройка spring находит учетные данные и пытается подключиться к базе данных с аутентификацией, что не удается, поскольку это встроенная база данных, которая еще не была инициализирована учетными данными.

Я пытался использовать mongeez, чтобы инициализировать учетные данные до весеннего запуска, но эта библиотека имеет та же проблема с определением учетных данных.

Итак, мой настоящий вопрос:

Есть ли способ инициализировать встроенную базу данных с аутентификацией? Я копался в исходном коде и ничего не нашел.


person petesavitsky    schedule 24.01.2018    source источник
comment
Не могли бы вы добавить текущую конфигурацию для prod, а также для integ-тестов?   -  person fateddy    schedule 25.01.2018
comment
У меня такая же проблема. Хотелось бы знать, если / когда на это ответят. Я получаю com.mongodb.MongoSecurityException: исключение аутентификации MongoCredential   -  person user26270    schedule 12.02.2018
comment
@ user26270, к сожалению, я так и не нашел способ сделать это. Вместо этого мне пришлось полностью удалить учетные данные из конфигурации и добавить их во время выполнения во время производственного развертывания. Таким образом, интеграционные тесты не смогут проверить аутентификацию.   -  person petesavitsky    schedule 13.08.2018


Ответы (2)


Я была такая же проблема. Вот как это работает для меня (используя Kotlin):

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT, properties = ["spring.data.mongodb.port="])
class IntegrationTests {

@Autowired
private val webClient: WebTestClient? = null

@Autowired
private val mongoConfig: IMongodConfig? = null
var collection: MongoCollection<Document>? = null

fun createDBAndCollection(collectionName: String){
    val mongo = MongoClient("127.0.0.1", mongoConfig!!.net().port)
    val db = mongo.getDatabase("local")
    db.createCollection(collectionName)
    collection = db.getCollection(collectionName)
}

@Test
fun `Find all tracks on JSON REST endpoint`() {
    createDBAndCollection("track")
    collection?.insertOne(Document("key", "val"))

    webClient!!.get().uri("/reactive/tracks")
            .accept(APPLICATION_JSON)
            .exchange()
            .expectStatus().is2xxSuccessful
            .expectBodyList<Track>()
            .hasSize(1);
}
}
  • Нет необходимости изменять application.properties. Достаточно очистить настройку порта с помощью аннотации SprintBootTest (другие подходы у меня не сработали, например, @TestPropertySource)
  • mongoConfig вводится и используется для получения случайного порта, сгенерированного флапдудлом.
  • имя базы данных должно совпадать с именем в application.properties (хотя я уверен, что есть способ прочитать это динамически во время выполнения).

Мои тестовые зависимости Gradle:

testImplementation('de.flapdoodle.embed:de.flapdoodle.embed.mongo')
testImplementation('io.projectreactor:reactor-test')
testImplementation('org.springframework.boot:spring-boot-starter-test')
testImplementation("org.junit.jupiter:junit-jupiter-api")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine")
person bubblez    schedule 15.11.2018

На самом деле вы можете создать аутентифицированного пользователя, просмотрев свою admin.system.users коллекцию. Просто создайте тестового пользователя и поместите его туда с помощью клиента mongo. Как только у вас появится пользователь, вы можете сбросить этот документ и использовать этот json для создания нового аутентифицированного пользователя во встроенном наборе тестов mongo. Это будет что-то вроде этого:

private static void createAuthorizationUser() {
    MongoClient mongoClient = new MongoClient(HOST);
    MongoDatabase admin = mongoClient.getDatabase("admin");
    MongoCollection<Document> usersCollection = admin.getCollection("system.users");
    usersCollection.insertOne(Document.parse(""
            + "{\n" + 
            "    \"_id\": \"admin.test-user\",\n" + 
            //"    \"userId\": Binary(\"rT2Ig**********jGXZEQ==\", 4),\n" + 
            "    \"user\": \"test-user\",\n" + 
            "    \"db\": \"admin\",\n" + 
            "    \"credentials\": {\n" + 
            "        \"SCRAM-SHA-1\": {\n" + 
            "            \"iterationCount\": 10000,\n" + 
            "            \"salt\": \"gmm******GnNcAw==\",\n" + 
            "            \"storedKey\": \"qE***********8/LAvG7s=\",\n" + 
            "            \"serverKey\": \"Re*********eQh6w=\"\n" + 
            "        }\n" + 
            "    },\n" + 
            "    \"roles\": [\n" + 
            "        {\n" + 
            "            \"role\": \"readWrite\",\n" + 
            "            \"db\": \"test\"\n" + 
            "        }\n" + 
            "    ]\n" + 
            "}"
            + ""));
}

Я создал пользователя с именем test-user, который имеет привилегии readWrite для test db. По какой-то причине встроенному Mongo не нравится функция Binary, но простое комментирование не повредит функции аутентификации.

При создании клиента можно сделать просто через

MongoClient mongoClient = new MongoClient(
    new MongoClientURI( 
        String.format("mongodb://%s:%s@%s:%d/%s", "test-user", "****", "localhost", 27017, "admin" ) 
    )
);

Это должно решить проблему.

person Squake    schedule 14.06.2019