7

I'm trying to connect embedded mongodb and test it with MongoDbSpringIntegrationTest. The problem is that the identical code works with spring boot in 2.7.7 but doesn't work with spring boot in 3.0.0. The question is how can I enable embedded mongodb for spring boot tests in 3.0.0?

dependencies in pom.xml: `

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>de.flapdoodle.embed</groupId>
        <artifactId>de.flapdoodle.embed.mongo</artifactId>
        <version>3.5.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-mongodb</artifactId>
        <version>3.0.0</version>
    </dependency>
</dependencies>

`

application.properties: `

spring.data.mongodb.database=test
spring.data.mongodb.port=27017
spring.mongodb.embedded.version=4.0.2

MongoDbSpringIntegrationTest:

@DataMongoTest
@ExtendWith(SpringExtension.class)
public class MongoDbSpringIntegrationTest {
  @DisplayName("given object to save"
      + " when save object using MongoDB template"
      + " then object is saved")
  @Test
  public void test(@Autowired MongoTemplate mongoTemplate) {
    // given
    DBObject objectToSave = BasicDBObjectBuilder.start()
        .add("key", "value")
        .get();

    // when
    mongoTemplate.save(objectToSave, "collection");

    // then
    assertThat(mongoTemplate.findAll(DBObject.class, "collection")).extracting("key")
        .containsOnly("value");
  }
}

`

When I run this I get this error: org.springframework.dao.DataAccessResourceFailureException: Timed out after 30000 ms while waiting to connect. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused: no further information}}]

Suori
  • 71
  • 1
  • 2
  • 2
    Embedded mongo support was dropped in spring 2.7 Check this out: https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo.spring/tree/spring-3.0.x – Volodymyr Masliy Dec 11 '22 at 21:03

4 Answers4

10

The embedded mongo dependency you are using has support for Spring boot 2.7.x integration. There's a new version for Spring boot 3.x. You should only need to make 2 changes to your project:

Embedded Mongo dependency

Your pom.xml currently has:

<dependency>
    <groupId>de.flapdoodle.embed</groupId>
    <artifactId>de.flapdoodle.embed.mongo</artifactId>
    <version>3.5.3</version>
    <scope>test</scope>
</dependency>

Change that to:

<dependency>
    <groupId>de.flapdoodle.embed</groupId>
    <artifactId>de.flapdoodle.embed.mongo.spring30x</artifactId>
    <version>4.5.2</version>
    <scope>test</scope>
</dependency>

Notice the artifactId is different. Also 4.5.2 is the latest version at the time of this answer, find the latest anytime on maven.

Mongo version configuration

Your application.properties currently has:

spring.mongodb.embedded.version=4.0.2

Change that to:

de.flapdoodle.mongodb.embedded.version=4.0.2

The mongo version config is now resolved from flapdoodle's namespace, not Spring's.

egimaben
  • 653
  • 7
  • 22
  • 1
    That works for me. You can also remove `test`, disable autoconfiguration, and only turn on embedded MongoDB with certain Spring Boot profiles. There are gotchas here and there. I document the process at [Embedded MongoDB Only in IDE using Spring Boot 3.x](https://www.garretwilson.com/blog/2023/04/02/embedded-mongodb-ide-spring-boot-3). – Garret Wilson Apr 02 '23 at 21:24
  • import de.flapdoodle.embed.mongo.MongodExecutable -> cannot be resolved – pujan kc Jun 09 '23 at 06:33
2

Add to build.gradle:

// Embedded Mongo
implementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo.spring30x:4.6.2'

Add to the test properties next:

# Tests
de.flapdoodle.mongodb.embedded.version=5.0.5

enter image description here

And example of test:

@SpringBootTest
public class ExampleTest {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Test
    public void test() {
        mongoTemplate.save(MyEntity.builder()
                .name("test")
                .email("test@mail.com")
                .build());
    }
}
cheladon
  • 121
  • 1
  • 5
1

egimaben's answer helped me a lot. Although there need to be some other changes, I will share them within here just in case somebody needs.

I'm using an macbook pro m2 and our project is still using springboot 2.6.x, with spring.mongodb.embedded.version: 4.0.2 set in the test application's application.yaml file. And it's having issues as I started to use m2 to run the tests.

What I changed in build.gradle (like the egimaben's answer for maven):

from

testImplementation 'de.flapdoodle.embed:de.flapdoodle.embed.mongo'

to

testImplementation "de.flapdoodle.embed:de.flapdoodle.embed.mongo.spring27x:4.6.0"

also need to add:

dependencyManagement {
  dependencies {
    dependency group:'de.flapdoodle.embed', name:'de.flapdoodle.embed.mongo', version:"4.6.1"
  }
}

the de.flapdoodle.embed:de.flapdoodle.embed.mongo.spring27x:4.6.0 is needed and cannot change to ...spring26x:xxx, also the version 4.6.0 is important here.

The dependencyManagement section is meant to tell spring not use their own embedded mongodb as we are still using 2.6.x. The 4.6.1 in dependencyManagement section looks like the version 4.6.0 for the ...spring27x, but it's not the same. They are from two different repos:

  1. https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo.spring/tree/spring-3.0.x
  2. https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo

And last thing, about the test application's application.yaml file, you can now define the newest mongodb version as it is in the official website: https://www.mongodb.com/download-center/community/releases/archive.

I chose 6.0.2 which already supports the m2 with the version macOS ARM 64: Archive: mongodb-macos-arm64-6.0.2.tgz. So I changed the version inside the application.yaml file:

from

spring.mongodb.embedded.version: 4.0.2

to

de.flapdoodle.mongodb.embedded.version: 6.0.2

hope it helps the people with new macbook pro m2

peisun
  • 11
  • 3
0

Spring Boot 3 support has been added to flapdoodle as described in this issue and i found answer on my question in issues.

dan1st
  • 12,568
  • 8
  • 34
  • 67
Suori
  • 71
  • 1
  • 2
  • It would be helpful if you could also include the answer to your original problem in this answer. – dan1st Jan 21 '23 at 09:44