'@DataMongoTest is creating a null MongoTemplate

I have been trying to follow the instructions in the link below to try to add an automatically configured Embedded MongoDB Instance for Cucumber Integration testing. This is currently not working, since the I keep getting a null MongoTemplate. I thought that @DataMongoTest would automatically configure "@Autowired private MongoTemplate mongoTemplate;" Is this not the case? Below is my code:

mongoTemplate.save(doc, collection); throws a nullpointer exception.

@SpringBootTest(classes = AppCommentApiApplication.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@DataMongoTest
public abstract class SpringIntegrationTest {

    @Value("${local.server.port}")
    public int port;

    @Autowired
    private MongoTemplate mongoTemplate;

    protected void importJSON(String collection, String file) {
        try {
            for (String line : FileUtils.readLines(new File(file), "utf8")) {
                Document doc = Document.parse(line);
                mongoTemplate.save(doc, collection);
            }
        } catch (IOException e) {
            throw new RuntimeException("Could not import file: " + file, e);
        }
    }

}


@RunWith(Cucumber.class)
@CucumberOptions(format = "pretty",
                 features = "src/test/resources/features",
                 glue = "com.app.comment.cucumber")
public class CucumberIntegrationTest {
}


public class StepDefinitions extends SpringIntegrationTest {

    private Map<String, String> headerMap = null;
    private String postBody = null;
    private String putBody = null;
    private String formData = null;
    private Response response = null;
    private String data = null;

    private final static String MONGODB_COLLECTION = "comment";
    private final static String MONGODB_DATA = "src/test/resources/mongodb-data/data.txt";

    @Before
    public void setup() {
        importJSON(MONGODB_COLLECTION, MONGODB_DATA);
    }

    @Given("^the header information$")
    public void the_header_information(Map<String, String> headerMap) throws Throwable {
        this.headerMap = headerMap;
    }

    @Given("^post message body \"(.*?)\"$")
    public void post_message_body(String postBody) throws Throwable {
        this.postBody = postBody;
    }

    @Given("^put message body \"(.*?)\"$")
    public void put_message_body(String putBody) throws Throwable {
        this.putBody = putBody;
    }
}

pom.xml file:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.app.comment</groupId>
    <artifactId>app-comment-api</artifactId>
    <version>1.0.4</version>
    <packaging>jar</packaging>

    <name>app-comment-api</name>
    <description>App Comments Microservice</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.1.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <log4j.version>2.4.1</log4j.version>
        <commons.lang3.version>3.3.2</commons.lang3.version>
        <guava.version>19.0</guava.version>
        <swagger.version>2.4.0</swagger.version>
        <surefire.junit47.version>2.18.1</surefire.junit47.version>
        <rest-assured.version>2.8.0</rest-assured.version>
        <jacoco.version>0.7.5.201505241946</jacoco.version>
        <powermock.version>1.6.4</powermock.version>
        <commons.io.version>2.4</commons.io.version>
        <httpclient.version>4.5.1</httpclient.version>
        <jayway.jsonpath.version>2.2.0</jayway.jsonpath.version>
        <jjwt.version>0.6.0</jjwt.version>
        <docker.image.prefix>app</docker.image.prefix>
        <docker.spotify.plugin.version>0.4.5</docker.spotify.plugin.version>
        <jacoco.maven.plugin.version>0.7.7.201606060606</jacoco.maven.plugin.version>
        <fongo.version>2.0.11</fongo.version>
        <cucumber.version>1.2.5</cucumber.version>
        <gatling.highcharts.version>2.2.3</gatling.highcharts.version>
        <gatling.plugin.version>2.2.1</gatling.plugin.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-actuator-docs</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-zipkin</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-mongodb</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security.oauth</groupId>
            <artifactId>spring-security-oauth2</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.security</groupId>
            <artifactId>spring-security-jwt</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>io.dropwizard.metrics</groupId>
            <artifactId>metrics-core</artifactId>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger.version}</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>${swagger.version}</version>
        </dependency>

        <!-- Utility -->
        <dependency>
            <groupId>com.logentries</groupId>
            <artifactId>logentries-appender</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>${commons.io.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons.lang3.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.httpcomponents</groupId>
            <artifactId>httpclient</artifactId>
            <version>${httpclient.version}</version>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>${guava.version}</version>
        </dependency>
        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>${jayway.jsonpath.version}</version>
        </dependency>
        <dependency>
            <groupId>io.jsonwebtoken</groupId>
            <artifactId>jjwt</artifactId>
            <version>${jjwt.version}</version>
        </dependency>

        <dependency>
            <groupId>com.fasterxml.jackson.datatype</groupId>
            <artifactId>jackson-datatype-jsr310</artifactId>
            <version>2.6.5</version>
        </dependency>

        <!-- Test Dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.jayway.restassured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>${rest-assured.version}</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <artifactId>commons-logging</artifactId>
                    <groupId>commons-logging</groupId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>com.jayway.restassured</groupId>
            <artifactId>spring-mock-mvc</artifactId>
            <version>${rest-assured.version}</version>
            <scope>test</scope>
        </dependency>

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

        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-java</artifactId>
            <version>${cucumber.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-junit</artifactId>
            <version>${cucumber.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>info.cukes</groupId>
            <artifactId>cucumber-spring</artifactId>
            <version>${cucumber.version}</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>io.gatling.highcharts</groupId>
            <artifactId>gatling-charts-highcharts</artifactId>
            <version>${gatling.highcharts.version}</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR5</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- Package as a docker image -->
            <plugin>
                <groupId>com.spotify</groupId>
                <artifactId>docker-maven-plugin</artifactId>
                <version>${docker.spotify.plugin.version}</version>
                <configuration>
                    <serverId>docker-hub</serverId>
                    <imageName>${docker.image.prefix}/${project.artifactId}</imageName>
                    <dockerDirectory>src/main/docker</dockerDirectory>
                    <resources>
                        <resource>
                            <targetPath>/</targetPath>
                            <directory>${project.build.directory}</directory>
                            <include>${project.build.finalName}.jar</include>
                        </resource>
                    </resources>
                    <imageTags>
                        <imageTag>${project.version}</imageTag>
                    </imageTags>
                </configuration>
            </plugin>
            <!-- Runs Code Coverage Reports -->
            <plugin>
                <groupId>org.jacoco</groupId>
                <artifactId>jacoco-maven-plugin</artifactId>
                <version>${jacoco.maven.plugin.version}</version>
                <executions>
                    <execution>
                        <id>pre-unit-test</id>
                        <goals>
                            <goal>prepare-agent</goal>
                        </goals>
                    </execution>
                    <execution>
                        <id>post-unit-test</id>
                        <phase>test</phase>
                        <goals>
                            <goal>report</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                    <excludes>
                        <exclude>**/*IntegrationTest.java</exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
        <id>cucumber-tests</id>
        <build>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <configuration>
                        <excludes>
                            <exclude>none</exclude>
                        </excludes>
                        <includes>
                            <!-- Include your Cucumber tests, as an example -->
                            <exclude>**/*IntegrationTest.java</exclude>
                            <exclude>**/*Simulation.scala</exclude>
                        </includes>
                    </configuration>
                </plugin>
            </plugins>
        </build>
        </profile>
        <profile>
            <id>gatling-tests</id>
            <build>
                <plugins>
                    <plugin>
                        <groupId>io.gatling</groupId>
                        <artifactId>gatling-maven-plugin</artifactId>
                        <version>${gatling.plugin.version}</version>
                        <executions>
                            <execution>
                                <goals>
                                    <goal>execute</goal>
                                </goals>
                                <configuration>
                                    <simulationClass>com.app.comment.gatling.MicroserviceServiceSimulation</simulationClass>
                                </configuration>
                            </execution>
                        </executions>
                        <configuration>
                            <configFolder>${project.basedir}/src/test/resources</configFolder>
                            <dataFolder>${project.basedir}/src/test/resources/data</dataFolder>
                            <resultsFolder>${project.basedir}/target/gatling/results</resultsFolder>
                            <bodiesFolder>${project.basedir}/src/test/resources/bodies</bodiesFolder>
                            <simulationsFolder>${project.basedir}/src/test/scala</simulationsFolder>
                            <runDescription>This-is-the-run-description</runDescription>
                            <!--    <noReports>false</noReports> -->
                            <!--   <reportsOnly>directoryName</reportsOnly> -->
                            <!--   <simulationClass>foo.Bar</simulationClass> -->
                            <!--   <jvmArgs> -->
                            <!--     <jvmArg>-DmyExtraParam=foo</jvmArg> -->
                            <!--   </jvmArgs> -->
                            <!--    <fork>true</fork> -->
                            <!--    <propagateSystemProperties>true</propagateSystemProperties> -->
                            <!--   <failOnError>true</failOnError> -->
                        </configuration>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

</project>

http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-testing-spring-boot-applications-testing-autoconfigured-mongo-test



Solution 1:[1]

If you use JUnit 4, you should have RunWith(SpringRunner.class). With JUnit 5 is not necessary.

And, @SpringBootTest cannot coexist with @DataMongoTest, because they are for different parts of the application and the latter is only for data part, while the former is for app part. (Actually the @BootstrapWith of them will conflict if you put these two together and the test cannot be start)

@DataMongoTest will use embedded database and you don't need to do extra config other than @Autowired the mongotemplate. If you want to use real db, do this:

@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)

My test is like this and it works:

@ActiveProfiles("db")
@DataMongoTest
class CouponTypeRefRepositoryTest {

    @Autowired
    private CouponTypeRefRepository repository; // a simple repository extending `DataMongoRepository`

    @Autowired
    private MongoTemplate mongoTemplate;


    @BeforeEach
    void prepare() {
        CouponTypeRef toSave = CouponTypeRef.builder()
                .id((short)1)
                .duration((short)1)
                .couponType("COMMERCIAL")
                .couponTypeRefConfig(CouponTypeRefConfig.REFUNDABLE_NORMAL)
                .build();
        mongoTemplate.save(toSave, "CouponTypeRef");
    }

    @Test
    void shouldReturnCouponTypeRef() {
        Optional<CouponTypeRef> optional = repository.findById((short)1);
        assertThat(optional.isPresent(), is(true));
        assertThat(optional.get().getCouponType(), is("COMMERCIAL"));
        assertThat(optional.get().getDuration(), is((short)1));
        assertThat(optional.get().getCouponTypeRefConfig(), is(CouponTypeRefConfig.REFUNDABLE_NORMAL));
    }

My dependency is:

implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive:2.2.1.RELEASE'

The db profile config:

spring:
  data:
    mongodb:
      host: localhost
      port: 27017
      database: app1

More info here: https://www.baeldung.com/spring-boot-embedded-mongodb https://docs.spring.io/spring-boot/docs/1.5.4.RELEASE/reference/html/boot-features-testing.html

Solution 2:[2]

Have you bean able to fix your problem ? I cannot get Spring Boot to start Embedded MongoDb instance on some random port, and more connect to it in that test throw that random port.

Solution 3:[3]

Adding @RunWith(SpringRunner.class) annotation to SpringIntegrationTest class should work. SpringRunner will enable Autowiring of beans into your test class.

Solution 4:[4]

Have you tired putting an @DirtiesContext on your test class?

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 Sniady
Solution 3 Areeb Ahmed
Solution 4 PCalouche