英文:
How to inject mongoclient to my POST service
问题
Controller:
@ApplicationScoped
@Path("/endpoint")
public class A {
@Inject
B service;
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Document add(List<? extends Document> list) {
return service.add(list);
}
}
Service Class:
@ApplicationScoped
public class B {
@Inject
MongoClient mongoClient;
private MongoCollection<Document> getCollection() {
return mongoClient.getDatabase(DBname).getCollection(coll);
}
public Document add(List<? extends Document> list) {
Document response = new Document();
getCollection().deleteMany(new BasicDBObject());
getCollection().insertMany(list);
response.append("count", list.size());
return response;
}
}
My JUnit class
I tried out many approaches discussed on the internet to set up the embedded mongo but none worked for me.
I want to invoke my POST service but actual mongodb must not get connected. My JUnit class is as below:
@QuarkusTest
public class test {
List<Document> request = new ArrayList<Document>();
Document doc = new Document();
doc.append("Id", "007")
.append("name", "Nitin");
request.add(doc);
given()
.body(request)
.header("Content-Type", MediaType.APPLICATION_JSON)
.when()
.post("/endpoint")
.then()
.statusCode(200);
}
英文:
I have a very simple Quarkus application which accepts input and insert it into MongoDB using MongoClient.
Controller:
@ApplicationScoped
@Path("/endpoint")
public class A {
@Inject
B service;
@POST
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public Document add(List<? extends Document> list) {
return service.add(list);
}
}
Service Class:
@ApplicationScoped
public class B {
@Inject
MongoClient mongoClient;
private MongoCollection<Document> getCollection() {
return mongoClient.getDatabase(DBname).getCollection(coll);
}
public Document add(List<? extends Document> list) {
Document response = new Document();
getCollection().deleteMany(new BasicDBObject());
getCollection().insertMany(list);
response.append("count", list.size());
return response;
}
}
As you see that my service removes existing data and inserts the new data. For JUnit testing, I am trying to set up embedded MongoDB and want my service call to use the embedded mongo. But no success.
My JUnit class
I tried out many approaches discussed on the internet to set up the embedded mongo but none worked for me.
I want to invoke my POST service but actual mongodb must not get connected. My JUnit class is as below:
@QuarkusTest
public class test {
List<Document> request = new ArrayList<Document>();
Document doc = new Document();
doc.append("Id", "007")
.append("name", "Nitin");
request.add(doc);
given()
.body(request)
.header("Content-Type", MediaType.APPLICATION_JSON)
.when()
.post("/endpoint")
.then()
.statusCode(200);
}
答案1
得分: 2
你需要在测试中使用不同的连接字符串,而不是在常规(生产)运行中使用相同的连接字符串。
Quarkus 可以使用配置文件来实现这一点,当运行 @QuarkusTest
测试时,会自动选择 %test
配置文件。
因此,你可以在你的 application.properties
中添加类似以下的内容:
quarkus.mongodb.connection-string=mongodb://host:port
%test.quarkus.mongodb.connection-string=mongodb://localhost:27017
在正常运行应用程序时,mongodb://host:port
将被使用,而在测试中将使用 mongodb://localhost:27017
。
然后,你可以使用 Flapdoodle 或 Testcontainers 在测试期间在本地启动 MongoDB 数据库。
关于配置文件的更多信息:https://quarkus.io/guides/config#configuration-profiles
关于如何从 Quarkus 测试中启动外部服务的更多信息:https://quarkus.io/guides/getting-started-testing#quarkus-test-resource
英文:
You need to use a different connection-string for your test than for your regular (production) run.
Quakus can use profiles to do this, the %test
profile is automatically selected when running @QuarkusTest
tests.
So you can add in your application.properties
something like this :
quarkus.mongodb.connection-string=mongodb://host:port
%test.quarkus.mongodb.connection-string=mongodb://localhost:27017
Here mongodb://host:port
will be use on the normal run of your application and mongodb://localhost:27017
will be used from inside your test.
Then you can use flapdoodle or Testcontainers to launch a MongoDB database on localhost during your test.
More information on configuration profiles: https://quarkus.io/guides/config#configuration-profiles
More information on how to start an external service from a Quarkus test: https://quarkus.io/guides/getting-started-testing#quarkus-test-resource
答案2
得分: 1
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());
}
}
Reference: https://stackoverflow.com/questions/6437226/embedded-mongodb-when-running-integration-tests
英文:
Have u tried flapdoodle:
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());
}
}
Reference : https://stackoverflow.com/questions/6437226/embedded-mongodb-when-running-integration-tests
答案3
得分: 0
感谢大家的建议。我在application.properties文件中声明了测试集合。当我们运行junit时,%test配置文件会自动激活,因此我的服务会自动选择测试集合。在我的junit测试用例完成后,我删除了测试集合。
英文:
Thanks everyone for suggestions. I declared test collections in application.properties file. %test profile automatically get activated when we run junits, so automatically my services picked up the test collections. I deleted the test collections after my junit test cases got completed.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论