简体   繁体   中英

How to prevent using production MongoDB URI in spock micronaut tests

How can I ensure that my tests will never use the production MongoDB URI in my Micronaut application?

I am currently using an embedded server in my test configuration to run my tests with a test MongoDB container, like this:

@MicronautTest
class JwtAuthenticationSpec extends Specification {

final MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:6.0.3"))
        .withExposedPorts(27017)

def setup() {
    mongoDBContainer.start()
    embeddedServer = ApplicationContext.run(EmbeddedServer,
            ['mongodb.uri': "${mongoDBContainer.connectionString}/fire"]) //sets the uri to the test containers one
}
//...

And my MongoDB configuration in my application.yml is like this:

mongodb:
  uri: ${MONGO_PROD_URI}

My fear here is that a future developer could create a new test, using a new client without the embedded server, this would mean that the test would use the production url right? How can I avoid this to make sure that the tests will NEVER use the production url?

Look at Micronaut Test Resources for MongoDB .

See the Guide Access a MongoDB Database with Micronaut Data MongoDB demonstrating using MongoDB with Micronaut Test Resources and how to run in production:

When the application is started locally — either under test or by running the application — resolution of the property mongodb.uri is detected and the Test Resources service will start a local MongoDB docker container, and inject the properties required to use this as the datasource.

When running under production, you should replace this property with the location of your production MongoDB instance via an environment variable.

MONGODB_URI=mongodb://username:password@production-server:27017/databaseName

More Information

The section on MongoDB in the Test Resource document is sparse. From the Introduction section:

Test resources are only available during development (for example when running the Gradle run task or the Maven mn:run goal) and test execution: production code will require the resources to be available.

In a nutshell, Micronaut Test Resources handles spinning up your TestContainers for you.

Test Resources wouldn't stop a developer from setting the Production URI as an environment variable or the properties file.

You could do something like:

/test/java/com/example/MongoContainer.java

@Factory
@Requires(env = Environment.TEST)
@Replaces(factory = DefaultMongoClientFactory.class)
public class MongoContainer {

    @Bean(preDestroy = "close")
    @Singleton
    @Primary
    public MongoClient create(MongoClientSettings settings) {
        MongoDBContainer container = new MongoDBContainer(DockerImageName.parse("mongo:6.0.3"))
                .withExposedPorts(27017);
        container.start();

        MongoClientSettings testClientSettings = MongoClientSettings.builder(settings).applyConnectionString(
                new ConnectionString(container.getConnectionString() + "/fire")).build();

        return MongoClients.create(testClientSettings);
    }
}

Which will ignore the mongodb.uri property all together for the test environment and your test cases wouldn't need to start the container. Note: could also add a property for the image name ( "mongo:6.0.3" ) in the factory above.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM