Jiří Kraml
Jiří Kraml

Reputation: 101

How to use custom converters with @DataMongoTest?

I have a test instantiating some entities, saving them to MongoDB and loading them again to make sure the mapping works corretly. I'd like to use the @DataMongoTest annotation on the test class to make sure an embedded MongoDB instance is dynamically created.

This worked just fine until I had to introduce custom converters (org.springframework.core.convert.converter.Converter) for some classes. These are set up like this:

@ReadingConverter
public class MyClassReadConverter implements Converter<Document, MyClass> {
...

@WritingConverter
public class MyClassWriteConverter implements Converter<MyClass, Document> {
...

@Configuration
public class SpringMongoSetup extends AbstractMongoConfiguration {
    @Override
    public Mongo mongo() throws Exception {
        //I don't want that in the test..
        return new MongoClient("localhost"); 
    }

    @Override
    public CustomConversions customConversions() {
        // ..but I need this
        List<Converter<?,?>> converters = new ArrayList<>();
        converters.add(new MyClassWriteConverter());
        converters.add(new MyClassReadConverter());
        return new CustomConversions(converters);
    }
...

For normal (non-test) execution this works just fine. The test also works if I use the @SpringBootTest annotation which makes the test use my configuration. Unfortunately, this configuration also defines the host/port for MongoDB, but I'd like to use the host/port of the embedded MongoDB started by @DataMongoTest.

Can I somehow configure it so that either @DataMongoTest uses the custom converters with the embedded MongoDB, or that I can get the embedded host/port while instantiating my configuration class?

Upvotes: 10

Views: 3120

Answers (3)

vicangel
vicangel

Reputation: 162

I think the recommended way is (using junit5):

@DataMongoTest
@ContextConfiguration(classes = MongoConfig.class)
public class MyMongoTest { ... }

In your MongoConfig.class you have the configuration that your actual application uses.

Upvotes: 0

jrd
jrd

Reputation: 3137

To use CustomConverters with @DataMongoTest you need to expose those converters as a Spring bean, e.g.:

@Configuration 
public class CustomConversionsConfiguration {

    @Bean
    public CustomConversions customConversions() {
        List<Converter<?,?>> converters = new ArrayList<>();
        converters.add(new MyClassWriteConverter());
        converters.add(new MyClassReadConverter());
        return new CustomConversions(converters);
    }

}

...and use the configuration in Mongo test classes:

@RunWith(SpringRunner.class)
@DataMongoTest
@Import(CustomConversionsConfiguration.class)
public class MyMongoTest { ... }

Upvotes: 6

Stephane Nicoll
Stephane Nicoll

Reputation: 33131

If you are using slicing we will disable all scanning that isn't relevant to Mongo. We have no way to know that your SpringMongoSetup is related to Mongo so, since we don't scan it, it's not applied.

If you do not rely on the auto-configuration for Mongo, you'll have to import that class yourself. You can do so with @Import, e.g.

@RunWith(SpringRunner.class)
@DataMongoTest
@Import(SpringMongoSetup.class)
public class MyMongoTest { ... }

Upvotes: 0

Related Questions