4

I am using mongo in my spring project, but I cant connect to mongo server. Anyone knows a way to ignore this bean when executing tests, because sometimes I dont have the mongo server up and I dont want that this build fail.

I really like to know if I can ignore it using SpringRunner.

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { Application.class })
public class ApplicationTests {
    @Test
    public void contextLoads() {
    }
}

Stacktrace:

Caused by: org.springframework.dao.DataAccessResourceFailureException: 
Timed out after 30000 ms while waiting for a server that matches WritableServerSelector. 
Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: localhost}, caused by {java.net.UnknownHostException: localhost}}]; nested exception is com.mongodb.MongoTimeoutException: Timed out after 30000 ms while waiting for a server that matches WritableServerSelector. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketException: localhost}, caused by {java.net.UnknownHostException: localhost}}]

Spring components:

<parent>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-parent</artifactId>
    <version>Dalston.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>

PS I stopped the mongodb at localhost intentionally.

bpedroso
  • 4,617
  • 3
  • 29
  • 34

2 Answers2

8

You can disable Spring Boot's auto configuration of MongoDB by adding the following annotation to your ApplicationTests class:

@EnableAutoConfiguration(exclude={MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})

This will prevent Spring Boot from creating the MongoClient (assuming there are no other classes in your test context annotated with @EnableAutoConfiguration or @SpringBootApplication).

glytching
  • 44,936
  • 9
  • 114
  • 120
  • 2
    Im going to assume his `Application.class` has `@SpringBootApplication`. Another option is to use an embedded mongo dependency for tests: ` de.flapdoodle.embed de.flapdoodle.embed.mongo test ` – aorticDefiance Aug 09 '17 at 16:29
  • 1
    I'm triying this approach, using embedded mongo. The answer above answer how to exclude the autoconfiguration, but my problem isnt solved yet. – bpedroso Aug 09 '17 at 16:42
2

I solved using embedded mongodb.

Dependency (https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo):

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

I added specific configuration on application-test.yml (execute using spring.profile.active=test)

spring:
  data:
    mongodb:
      database: dbtest
      host: localhost
      port: 27028

And the ApplicationTests.java

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { Application.class })
public class ApplicationTests {

    private static final String LOCALHOST = "127.0.0.1";
    private static final String DB_NAME = "dbtest";
    private static final int MONGO_TEST_PORT = 27028;
    private static MongodProcess mongoProcess;
    private static Mongo mongo;

    @BeforeClass
    public static void initializeDB() throws IOException {
        MongodStarter starter = MongodStarter.getDefaultInstance();
        IMongodConfig mongodConfig = new MongodConfigBuilder()
            .version(Version.Main.V3_3)
            .net(new Net(LOCALHOST, MONGO_TEST_PORT, Network.localhostIsIPv6()))
            .build();

        MongodExecutable mongodExecutable = null;
        try {
            mongodExecutable = starter.prepare(mongodConfig);
            mongoProcess = mongodExecutable.start();
            mongo = new MongoClient(LOCALHOST, MONGO_TEST_PORT);
            mongo.getDB(DB_NAME);
        } finally {
            if (mongodExecutable != null)
                mongodExecutable.stop();
        }
    }

    @Test
    public void contextLoads() {}

    @AfterClass
    public static void shutdownDB() throws InterruptedException {
        if (mongo != null) mongo.close();
        if (mongoProcess != null) mongoProcess.stop();
    }
}
bpedroso
  • 4,617
  • 3
  • 29
  • 34