20

I am trying to write integration test case for one of my rest application which uses mongodb internally to persist the data

@DataMongoTest 
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class MainControllerTest {
@LocalServerPort
    private int port = 8080;
/* some test cases*/ 
}

but I am getting below error

java.lang.IllegalStateException: Configuration error: found multiple declarations of @BootstrapWith for test class [com.sample.core.controller.MainControllerTest]: [@org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.autoconfigure.data.mongo.DataMongoTestContextBootstrapper), @org.springframework.test.context.BootstrapWith(value=class org.springframework.boot.test.context.SpringBootTestContextBootstrapper)]

looks like these two are mutually exclusive, so how to do the integration testing .

scoder
  • 2,451
  • 4
  • 30
  • 70
  • See this question, comment and answer: https://stackoverflow.com/questions/45860899/springboot-how-can-i-perform-an-integration-test-with-real-dependencies – Jaap Apr 16 '19 at 11:41
  • Possible duplicate of [Springboot: How can I perform an integration test with real dependencies?](https://stackoverflow.com/questions/45860899/springboot-how-can-i-perform-an-integration-test-with-real-dependencies) – Jaap Apr 16 '19 at 11:42
  • 1
    this solved my question: https://stackoverflow.com/questions/48039644/how-to-make-the-junit-tests-use-the-embedded-mongodb-in-a-springboot-application – scoder Apr 16 '19 at 11:57

3 Answers3

15

Use @AutoConfigureDataMongo with @SpringBootTest and this will resolve this ambiguity issue. @SpringBootTest and @DataMongoTest cannot be used together.

Jestin Mathew
  • 166
  • 2
  • 4
0

Answering to a very old post hoping it may help others. @AutoConfigureDataMongo will connect to real database. In order to still use the embedded mongo, one can initiate the embedded mongoDb manually.

@SpringBootTest(classes = SubscriptionEventApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class SubscriptionEventApiIntegrationTest {


@BeforeAll
    static void setup() throws Exception {
        startEmbeddedMongoDbManually();
    }
    
    private static void startEmbeddedMongoDbManually() throws IOException {
        final String connectionString = "mongodb://%s:%d";
        final String ip = "localhost";
        final int port = 27017;
    
        ImmutableMongodConfig mongodConfig = MongodConfig
                .builder()
                .version(Version.V3_5_5)
                .net(new Net(ip, port, Network.localhostIsIPv6()))
                .build();
    
        MongodStarter starter = MongodStarter.getDefaultInstance();
        mongodExecutable = starter.prepare(mongodConfig);
        mongodExecutable.start();
        mongoTemplate = new MongoTemplate(MongoClients.create(String.format(connectionString, ip, port)), "test");
    }
    
    @AfterAll
    static void clean() {
        mongodExecutable.stop();
    }

    @Test
    public void test() {
    .....
    }
 }
Purushothaman
  • 417
  • 4
  • 6
0

Purushothaman suggested starting embedded MongoDB server manually. I am suggesting to start it automatically using @DataMongoTest, but creating WebTestClient manually instead.

Kotlin code below, translates to Java trivially:

@DataMongoTest
// @ContextConfiguration may not be needed for your case.
@ContextConfiguration(
    classes = [
        Application::class,
        MainController::class,
        // Add more needed classes for your tests here.
        // ...
    ]
)
@TestPropertySource(properties = ["spring.mongodb.embedded.version=4.0.12"])
class MainControllerTest(
    @Autowired
    private val mainController: MainController,
    // Add more beans needed for your tests here.
    // ...
) {
    // Creating a WebTestClient is easy and
    // can be done in different ways.
    // Here is one of the possible ways.
    private val webTestClient: WebTestClient =
        WebTestClient.bindToController(mainController).build()

    @Test
    fun someTest() {
        // ...
    }
}
Alexei Khlebnikov
  • 2,126
  • 1
  • 21
  • 21