mongock icon indicating copy to clipboard operation
mongock copied to clipboard

Better support for Spring Boot's @DataMongoTest

Open rfelgent opened this issue 2 years ago • 8 comments

Hello,

mongock gets triggered in a test without any problem when performing a fully fledged spring boot test e.g.

@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
@Testcontainers   // spinning up mongdb container by testcontainers library
class ApplicationIT {
}

Mongock is failing when doing a mongo slice test

@DataMongoTest
@Import(MongockConfig.class)   // a dedicated config class for mongock stuff like `@EnableMongock` and other beans that are only required for mongock migration stuff
@Testcontainers // spinning up mongdb container by testcontainers library
class RepositoryIT {
}

I found a way to fix this by manually adding a driver bean to the spring context

@TestConfiguration
  static class Fixture {

    @Bean
    public SpringDataMongoV3Driver driver(@Autowired MongoTemplate mongoTemplate) {
      return SpringDataMongoV3Driver.withDefaultLock(mongoTemplate);
    }

  }

So I do observe that Mongock's autoconfiguration for "driver" beans is failing within a @DataMongoTest. I am using SB 2.7 and SB 2.6.X and only the Mongock version is 5.1.0

Best regards

rfelgent avatar Jun 24 '22 09:06 rfelgent

problem still exists with Mongock 5.1.6 and Spring Boot 2.6.5 (Spring-Data-MongoDB v3.3.3)

rfelgent avatar Sep 23 '22 02:09 rfelgent

Hello @rfelgent ,

we are in the middle of something important right now. Is this blocking you? Thanks

dieppa avatar Sep 28 '22 06:09 dieppa

We have to add this configuration with @DataMongoTest:

@DataMongoTest
@EnableMongock
@Import({SpringDataMongoV4Context.class}) // it can be also SpringDataMongoV3Context for Spring Boot 2

Mainly find the SpringDataMongoV4Context was a little tricky. It is an autoconfiguration class. For enabling this autoconfiguration also for tests you need to add this file META-INF/spring/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo.imports With this content:

io.mongock.driver.mongodb.springdata.v4.config.SpringDataMongoV4Context

When I find some time I will create a MR.

Saljack avatar Apr 05 '23 10:04 Saljack

Hi @Saljack ,

exactly; either use V3Context.class oder V4Context.class depending on the Sprint Boot version you use.

Are you planning to create meta annatotation ? My 2 cents:

  • Is there one meta annotation supporting all Spring Boot versions or a dedicated annotation for each Spring Boot versions ?
  • furthermore, the mongock team has a different approach and a dedicated chapter for doing integration tests. I am not sure, what way to go or if multiple approaches/integrations should be supported by mongock itself

rfelgent avatar Apr 05 '23 13:04 rfelgent

Hmm, I realized it is not a good idea to just add META-INF/spring/org.springframework.boot.test.autoconfigure.data.mongo.AutoConfigureDataMongo.imports because it is then in production code. So I think using @Import({SpringDataMongoV4Context.class}) with @EnableMongock is cleaner solution. Otherwise, there would be a mongock-spring-test with this configuration but I do not see it as an advantage to add another test dependency. We have our custom testing library on our project so we can add this autoconfiguration there.

Saljack avatar Apr 06 '23 05:04 Saljack

Hi @dieppa ,

I see that you have closed the issue. Is there now an out-of-the-box solution provided by mongock library ?

rfelgent avatar Jul 02 '23 06:07 rfelgent

hello again,

sorry to bother you guys. This issue is still relevant for me in my current project. I am using spring boot 3.2.2 and mongock 5.4.0. As you closed the issue, I would like to know what is the solution provided by mongock library?

My current work-around for tweaking the DataMongoTest slice-test is to use a custom meta-annotation as follow:

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@DataMongoTest
@AutoConfigureJson
@Import({MongockConfig.class, DataMongoTestFixture.TestConfig.class})
@Testcontainers
@DirtiesContext
public @interface DataMongoTestFixture {

  @TestConfiguration
  // https://github.com/mongock/mongock/issues/551
  class TestConfig {

    @Bean
    public SpringDataMongoV4Driver driver(@Autowired MongoTemplate mongoTemplate) {
      return SpringDataMongoV4Driver.withDefaultLock(mongoTemplate);
    }
  }
}

I have no problems with mongock initialization during test execution when using plain SpringBootTest

rfelgent avatar Feb 02 '24 07:02 rfelgent

It has been re-opened, we'll take a look to see th best option to approach this and will give you an answer with the estimation soon

dieppa avatar Feb 02 '24 08:02 dieppa