Skip to content

Latest commit

 

History

History
207 lines (164 loc) · 5 KB

File metadata and controls

207 lines (164 loc) · 5 KB

Usage

You must disable the auto configuration provided by spring by disabling the spring provided auto configuration class:

@DataMongoTest()
@ExtendWith(SpringExtension.class)
public class AutoConfigTest {
  @Test
  void example(@Autowired final MongoTemplate mongoTemplate) {
    Assertions.assertThat(mongoTemplate.getDb()).isNotNull();
  }
}

Test Isolation

Per default there is just one mongodb instance running. In case you need test isolation you can annotate your test with @TestPropertySource as in this example:

@DataMongoTest()
@TestPropertySource(properties = "property=A")
@ExtendWith(SpringExtension.class)
@DirtiesContext
public class AutoConfigFirstIsolationTest {
  @Test
  void example(@Autowired final MongoTemplate mongoTemplate) {
    mongoTemplate.getDb().createCollection("deleteMe");
    long count = mongoTemplate.getDb().getCollection("deleteMe").countDocuments(Document.parse("{}"));

    assertThat(mongoTemplate.getDb()).isNotNull();
    assertThat(count).isEqualTo(0L);
  }
}

The tests with the same configuration will share their instance. If you want to achive test isolation with the same configuration you must annotate your test with @DirtiesContext so that this test will have his own mongodb:

@DataMongoTest()
@TestPropertySource(properties = "property=A")
@ExtendWith(SpringExtension.class)
@DirtiesContext
public class AutoConfigSecondIsolationTest {
  @Test
  void example(@Autowired final MongoTemplate mongoTemplate) {
    mongoTemplate.getDb().createCollection("deleteMe");
    long count = mongoTemplate.getDb().getCollection("deleteMe").countDocuments(Document.parse("{}"));

    assertThat(mongoTemplate.getDb()).isNotNull();
    assertThat(count).isEqualTo(0L);
  }
}

Transactions

To enable transactions with spring data, there is one minimal setup. Imagine you have an person repository:

public interface PersonRepository extends MongoRepository<Person,String> {
}

... which is called inside this service:

@Service
public class PersonService {

  private PersonRepository repository;
  
  @Autowired
  public PersonService(PersonRepository repository) {
    this.repository = repository;
  }

  @Transactional
  public void insert(String ... names) {
    for (String name : names) {
      repository.insert(new Person(name.substring(0, 1), name));
    }
  }

  public long count() {
    return repository.count();
  }
}

Then you must enable an MongoTransactionManager:

@Configuration
public class TransactionalConfig {

  @Bean
  MongoTransactionManager mongoTransactionManager(MongoDatabaseFactory dbFactory) {
    return new MongoTransactionManager(dbFactory);
  }

  @Bean
  MongodArguments mongodArguments() {
    return MongodArguments.builder()
      .replication(Storage.of("test", 10))
      .build();
  }
}

... and if we call the service from test, some calls will succeed and others will fail so that the transaction is not committed:

@AutoConfigureDataMongo
@SpringBootTest(
  properties = "de.flapdoodle.mongodb.embedded.version=5.0.5"
)
@EnableAutoConfiguration()
@DirtiesContext
public class TransactionalTest {

  @Test
  void personExample(@Autowired PersonService service) {
    service.insert("Klaus","Susi");

    assertThat(service.count()).isEqualTo(2);

    assertThatThrownBy(() -> service.insert("Helga","Hans"))
      .isInstanceOf(RuntimeException.class);

    assertThat(service.count()).isEqualTo(2);
  }
}

Custom Database Dir

@AutoConfigureDataMongo
@SpringBootTest(
  properties = {
    "de.flapdoodle.mongodb.embedded.databaseDir=${java.io.tmpdir}/customDir/${random.uuid}"
  }
)
@EnableAutoConfiguration()
@DirtiesContext
public class CustomDatabaseDirTest {

  @Test
  void example(@Autowired final MongoTemplate mongoTemplate) {
    Assertions.assertThat(mongoTemplate.getDb()).isNotNull();
  }
}

Customize Mongod

If none of the other configuration options is enough, you can customize it further by adding a BeanPostProcessor or use a more typesafe implementation like `TypedBeanPostProcessor:

@Configuration
public class LocalConfig {

  @Bean
  BeanPostProcessor customizeMongod() {
    return TypedBeanPostProcessor.applyBeforeInitialization(Mongod.class, src -> {
      return Mongod.builder()
        .from(src)
        .processOutput(Start.to(ProcessOutput.class)
          .initializedWith(ProcessOutput.namedConsole("custom")))
        .build();
    });
  }
}
@AutoConfigureDataMongo
@SpringBootTest()
@EnableAutoConfiguration
@DirtiesContext
public class CustomizeMongodTest {

  @Test
  void example(@Autowired final MongoTemplate mongoTemplate) {
    assertThat(mongoTemplate.getDb()).isNotNull();
  }

}

Config Prefix

Use 'de.flapdoodle.mongodb.embedded' as prefix in your config files.

Test with a real database

If you want to test with an 'unmanaged' mongodb database, you must disable the auto configuration by excluding EmbeddedMongoAutoConfiguration:

@EnableAutoConfiguration(exclude = {EmbeddedMongoAutoConfiguration.class})