4

I started playing with testcontainers and at the beginning of my journey I faced some issue (below). I did similar thing for mysql db and it worked fine. Do I miss some mongo specific config? According to [docs][1] there is not much to do.
Thanks in advance for any tips / examples.
com.mongodb.MongoSocketOpenException: Exception opening socket
at com.mongodb.internal.connection.SocketStream.open(SocketStream.java:70) ~[mongodb-driver-core-3.11.2.jar:na]
at com.mongodb.internal.connection.InternalStreamConnection.open(InternalStreamConnection.java:128) ~[mongodb-driver-core-3.11.2.jar:na]
at com.mongodb.internal.connection.DefaultServerMonitor$ServerMonitorRunnable.run(DefaultServerMonitor.java:117) ~[mongodb-driver-core-3.11.2.jar:na]
at java.base/java.lang.Thread.run(Thread.java:834) ~[na:na]

My code:
gradle.build

 testImplementation "org.testcontainers:spock:1.14.3"
 testImplementation "org.testcontainers:mongodb:1.14.3"

application.properties

spring.data.mongodb.uri=mongodb://127.0.0.1:27017/test

test

@Testcontainers
class TestContainersExample extends IntegrationSpec {
    @Shared
    MongoDBContainer mongoDb = new MongoDBContainer()

    def "setup"() {
        mongoDb.start()

        mongoDb.waitingFor(Wait.forListeningPort()
                .withStartupTimeout(Duration.ofSeconds(180L)));
    }


//test case
}
  
wacik93
  • 283
  • 1
  • 7
  • 16

2 Answers2

20

Testcontainers will map the MongoDB server port to a random port on your machine. That's why you can't hardcode spring.data.mongodb.uri=mongodb://127.0.0.1:27017/test in your property file.

A basic setup with JUnit 5 and Spring Boot >= 2.2.6 can look like the following

@Testcontainers
public class MongoDbIT {

  @Container
  public static MongoDBContainer container = new MongoDBContainer(DockerImageName.parse("mongo:5"));

  @DynamicPropertySource
  static void mongoDbProperties(DynamicPropertyRegistry registry) {
    registry.add("spring.data.mongodb.uri", container::getReplicaSetUrl);
  }


}

If you are using a different JUnit or Spring Boot version, take a look at the following guide for the correct Testcontainers setup.

magiccrafter
  • 5,175
  • 1
  • 56
  • 50
rieckpil
  • 10,470
  • 3
  • 32
  • 56
  • Yes, you were right. I forgot about port binding. Thanks! – wacik93 Jun 26 '20 at 18:53
  • @rieckpil But I can't just find `getReplicaSetUrl()`. I am using tescontainers:1.15.0 – Pradipta Sarma Dec 12 '20 at 07:19
  • I just updated one of my projects to Testcontainers 1.15.1 and for me the method is still available. Does your project include the MongoDB module (`org.testcontainers:mongodb:1.15.1`) or only Testcontainers? – rieckpil Dec 12 '20 at 07:59
  • 1
    @rieckpil - Thanks for your answer. I just visited your blog and also some YT videos on the same. Thanks for all of it. – d-coder Dec 14 '20 at 11:45
  • Thanks, that was exactly what I was looking for :) – geeksusma Jan 27 '21 at 11:41
  • `Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified` I'm facing the above error, I wonder if you guys have ever faced it?? – Nguyễn Đức Tâm Aug 27 '21 at 07:12
  • I have followed the example but:org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongo' defined in class path resource [org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mongodb.client.MongoClient]: Factory method 'mongo' threw exception; nested exception is java.lang.IllegalStateException: Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified – Andrew Mar 01 '22 at 00:44
  • Can you create a new question for this and add your test setup? – rieckpil Mar 01 '22 at 06:24
1

The full autowired example below works fine in Spring 6.0.X.

It correctly binds yout Repository and sets up the MongoClient

@DataMongoTest
@Testcontainers
public class TestContainersMongo {

    @Autowired
    UserRepository userRepository;

    @Container
    static MongoDBContainer mongoDBContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.10"));

    @DynamicPropertySource
    static void setProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.data.mongodb.uri", () -> mongoDBContainer.getReplicaSetUrl("embedded"));
    }

    @AfterEach
    void cleanUp() {
        userRepository.deleteAll();
    }

    @Test
    void shouldReturnListOfCustomerWithMatchingRate() {
        userRepository.insert(UserGenerator.generate(12));

        List<User> customers = userRepository.findAll();

        assertThat(customers).hasSize(12);
    }
}
Benjamin
  • 3,217
  • 2
  • 27
  • 42
  • I'm using Spring Boot 3.1.0 with Webflux. Found this one works for me. Here's my repository: https://github.com/yauritux/phone-booking-app. – yauritux May 22 '23 at 14:21