如何配置带有身份验证的嵌入式MongoDB以用于Spring启动集成测试?

时间:2018-01-24 22:53:14

标签: java mongodb spring-boot spring-data spring-data-mongodb

我有一个使用MongoDB进行持久化的Spring启动应用程序。我正在整合集成测试,我正在使用flapdoodle embedded mongo库来嵌入数据库。

这与弹簧靴自动配置相结合,一切都非常适合集成测试。然而,只要我为MongoDB添加身份验证凭据,一切都会崩溃。

我的理解是spring spring-configure找到凭据并尝试使用身份验证连接到数据库,但失败了,因为它是一个尚未使用凭据初始化的嵌入式数据库。

我尝试使用mongeez来初始化春季初启动时的凭据,但此库在凭据感知方面存在同样的问题。

所以我真正的问题是:

有没有办法通过身份验证初始化嵌入式数据库?我一直在挖掘源代码并且没有找到任何东西。

2 个答案:

答案 0 :(得分:1)

我有同样的问题。这是对我有用的方法(使用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被注入并用于检索由flappoodle生成的随机端口
  • 数据库名称必须与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")

答案 1 :(得分:0)

实际上,您可以通过查看您的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的用户,该用户对test db具有readWrite特权。出于某种原因,嵌入式Mongo不喜欢Binary函数,只是对其进行注释不会损害身份验证功能。

创建客户时,您可以简单地通过

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

应该可以解决问题。