spring - @DataMongoTest 正在创建一个空的 MongoTemplate

标签 spring mongodb spring-boot spring-data-mongodb spring-boot-test

我一直在尝试按照以下链接中的说明添加自动配置的嵌入式 MongoDB 实例以进行 Cucumber 集成测试。这目前不起作用,因为我一直得到一个空的 MongoTemplate。我以为@DataMongoTest 会自动配置“@Autowired private MongoTemplate mongoTemplate;”不是这样吗?以下是我的代码:

mongoTemplate.save(doc, collection);抛出空指针异常。

@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 文件:

<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

最佳答案

如果你使用 JUnit 4,你应该有 RunWith(SpringRunner.class)。不需要 JUnit 5。

并且,@SpringBootTest不能与@DataMongoTest共存,因为它们是针对应用程序的不同部分,后者只针对数据部分,而前者针对应用程序部分。 (其实@BootstrapWith放在一起会冲突,无法启动测试)

@DataMongoTest 将使用嵌入式数据库,除了 @Autowired mongotemplate 之外你不需要做额外的配置。如果你想使用真正的数据库,这样做:

@DataMongoTest(excludeAutoConfiguration = EmbeddedMongoAutoConfiguration.class)

我的测试是这样的,它有效:

@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));
    }

我的依赖是:

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

db 配置文件配置:

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

更多信息在这里: 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

关于spring - @DataMongoTest 正在创建一个空的 MongoTemplate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42317261/

相关文章:

node.js - Mongoose 按对象的对象值排序

java - Spring Boot-如何通过实现BeforeAllCallback的自定义扩展类设置或覆盖application.yml中定义的属性?

java - 如果在 xml 中手动创建 bean,Spring 注入(inject)将不起作用

java - 在 Spring boot 应用程序项目中使用 Wildfly

java - RequestMapping 占位符在 JUnit 测试中不起作用

mongodb - PHP/MongoDB : pushing an array value into array field with the $pushAll modifier

java - SpringBoot运行时动态外部配置Jar文件

MongoDB - 嵌入文档列表中的 $addToSet

java - 无法将 'logging.level.com.netflix.eureka' 下的属性绑定(bind)到 org.springframework.boot.logging.LogLevel

java - 如何从可选 Java 对象的数组中删除所有项目?