【问题标题】:TestNG test not using TestPropertySource for injecting @ValueTestNG 测试不使用 TestPropertySource 注入 @Value
【发布时间】:2018-01-24 18:56:04
【问题描述】:

我正在尝试为具有从属性文件注入的字段值的类编写测试。我试图在运行 TestNG 测试时利用 TestPropertySource 注释在其中获取值,但它似乎忽略了我的属性文件。

有许多类似的问题,我尝试仔细阅读并尽可能尝试它们的实现。不过,我的问题似乎略有不同,原因如下:

您需要做什么才能获得一个带有@Value 注释字段的被测单元,并设置了它们的属性?我可以以某种方式请求 spring 为我提供我的类的实例,而不是自己newing 他们吗?

这是一个最小的复制。

Foo.java

package nl.jeroenheijmans.stackoverflow.testngprops;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class Foo {
    @Value("${my.prop}")
    private String myProp;

    public String ExposeProp() {
        return myProp;
    }
}

FooTest.java

package nl.jeroenheijmans.stackoverflow.testngprops;

import org.springframework.test.context.TestPropertySource;
import org.testng.Assert;
import org.testng.annotations.Test;

@TestPropertySource("classpath:application.properties")
public class FooTest {
    @Test
    public void sanityCheck(){
        Foo foo = new Foo();
        Assert.assertNotNull(foo); // Success!
    }

    @Test
    public void testProperty() {
        Foo foo = new Foo();
        Assert.assertEquals(foo.ExposeProp(), "checkcheck"); // Fail!
    }
}

application.properties(在maintest 文件夹中)

my.prop=checkcheck

Main.java

package nl.jeroenheijmans.stackoverflow.testngprops;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
import org.springframework.context.annotation.PropertySource;

@SpringBootApplication
@PropertySource(value = {"classpath:application.properties"})
public class Main extends SpringBootServletInitializer {
    public static void main(String... args) {
        SpringApplication.run(Main.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(Main.class);
    }
}

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<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>nl.jeroenheijmans.stackoverflow</groupId>
    <artifactId>testngprops</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-all</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${org.springframework.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.testng</groupId>
                <artifactId>testng</artifactId>
                <version>${testng.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-all</artifactId>
                <version>${mockito.version}</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.version}</version>
                <configuration>
                    <source>${java.version}</source>
                    <target>${java.version}</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.version>3.5</maven.compiler.version>
        <org.springframework.boot.version>1.5.1.RELEASE</org.springframework.boot.version>
        <testng.version>6.9.10</testng.version>
        <mockito.version>1.9.5</mockito.version>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
</project>

【问题讨论】:

    标签: java maven spring-boot testng


    【解决方案1】:

    这是我解决这个问题的方法。

    简而言之,我相信您错过了扩展org.springframework.test.context.testng.AbstractTestNGSpringContextTests 并通过@Autowire 注释为对象Foo 使用依赖注入的部分。由于您正在实例化 Foo 对象,因此没有将值注入其中,这就解释了断言失败的原因。

    Main.java

    package com.rationaleemotions.stackoverflow.qn45716815;
    
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration;
    import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
    import org.springframework.boot.builder.SpringApplicationBuilder;
    import org.springframework.boot.web.support.SpringBootServletInitializer;
    import org.springframework.context.annotation.PropertySource;
    
    @SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})
    @PropertySource(value = {"classpath:application.properties"})
    public class Main extends SpringBootServletInitializer {
        public static void main(String... args) {
            SpringApplication.run(Main.class, args);
        }
    
        @Override
        protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
            return application.sources(Main.class);
        }
    }
    

    使用@SpringBootApplication(exclude = {MongoAutoConfiguration.class, MongoDataAutoConfiguration.class})的原因可以在这个帖子中找到:Mongo tries to connect automatically to port 27017(localhost)

    更新: 排除 Mongo 配置是可选的,如果您有一个为 Mongo 正确设置的项目,则无需这样做。 p>

    这是 FooTest.java 的样子

    package com.rationaleemotions.stackoverflow.qn45716815;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;
    import org.springframework.test.context.TestPropertySource;
    import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
    import org.testng.Assert;
    import org.testng.annotations.Test;
    
    @TestPropertySource("classpath:application.properties")
    @SpringBootTest
    public class FooTest extends AbstractTestNGSpringContextTests{
        @Autowired
        private Foo foo;
    
        @Test
        public void sanityCheck() {
            Assert.assertNotNull(foo);
        }
    
        @Test
        public void testProperty() {
            Assert.assertEquals(foo.ExposeProp(), "checkcheck");
        }
    }
    

    这是我的 maven 依赖项的样子

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>1.5.6.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>1.5.6.RELEASE</version>
        <scope>test</scope>
    </dependency>
    

    为 spring-boot-starter-logging 添加排除项的原因可以在这里找到:Disable Logback in SpringBoot

    更新: 排除 logback 是可选的,如果你有一个正确设置为使用 logback 的项目,你不需要这样做。

    这是我运行此测试时的输出:

    objc[36167]: Class JavaLaunchHelper is implemented in both /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/bin/java (0x1026784c0) and /Library/Java/JavaVirtualMachines/jdk1.8.0_131.jdk/Contents/Home/jre/lib/libinstrument.dylib (0x1027404e0). One of the two will be used. Which one is undefined.
    log4j:WARN No appenders could be found for logger (org.springframework.test.context.BootstrapUtils).
    log4j:WARN Please initialize the log4j system properly.
    
      .   ____          _            __ _ _
     /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
     \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
      '  |____| .__|_| |_|_| |_\__, | / / / /
     =========|_|==============|___/=/_/_/_/
     :: Spring Boot ::        (v1.5.6.RELEASE)
    
    
    ===============================================
    Default Suite
    Total tests run: 2, Failures: 0, Skips: 0
    ===============================================
    

    【讨论】:

    • 谢谢你的答案,过会儿去看看。 (我对 Mongo 弹出的方式感到困惑,没有意识到链中的某个地方存在与 mongo 相关的依赖项。)
    • @SpringBootTest + ...extends AbstractTestNGSpringContextTests + @AutoWired 属性成功了。 Mongo 的东西、Logback 的东西和 Log4j 的东西并不是让我的测试通过的必要条件。
    • 无论如何:感谢您的见解!如果这最终成为我的最终解决方案,我当然会记得接受答案(尽管请参阅我之前的评论,mongo/logging 的东西似乎无关紧要?)。我不确定的一件事是,这一切都意味着我正在运行集成测试而不是单元测试,需要稍微考虑一下,看看是否有(或者我应该)采取另一种方法。 - 再次感谢您的出色帮助!
    • @Jeroen - 我已经包含了我为使该解决方案起作用而遵循的所有内容,并且在匆忙中,我忘记了调用应该是可选的步骤。如果您的项目已正确配置为使用 Mongo 配置排除项(在我的情况下,我只是在使用示例项目)并且 logback 也是如此。我已经更新了我的答案,明确地将这两个步骤称为可选步骤。
    • 好的,谢谢您的澄清。我仍在使用 spring-boot 进行学习,因此了解为什么需要(不需要)每次更改都会很有帮助。
    猜你喜欢
    • 2011-07-26
    • 1970-01-01
    • 2012-10-17
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 2019-12-03
    • 2015-12-14
    相关资源
    最近更新 更多