我正在尝试为具有从属性文件注入的字段值的类编写测试。我正在尝试利用TestPropertySource
注释在运行TestNG测试时获取值,但它似乎忽略了我的属性文件。
有几十个类似的问题,我试着仔细阅读并尝试尽可能的实施。看来我的问题略有不同,原因如下:
“@TestPropertSource and @PropertySource don't work for JUnit”:谈论JUnit而不是TestNG(可能或可能不相关?),它还讨论了将属性值注入 test 阶级(与被测单位相对)。
“@TestPropertySource not working?”:讨论如何忽略缺失的属性,而不是如何修复它。
“@TestPropertySource is not loading properties”:还讨论了如何在测试类字段中注入值(尝试@RunWith
或@SpringBootTest
,但这也无济于事。)
Google search results中的其他链接也无济于事。
您需要做些什么才能使用@Value
带注释字段的属性设置被测单元?我可以以某种方式请求spring为我提供班级实例,而不是自己new
吗?
这是一个最小的复制品。
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(在main
和test
文件夹中)
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>
答案 0 :(得分:2)
以下是我解决这个问题的方法。
简而言之,我相信您错过了扩展org.springframework.test.context.testng.AbstractTestNGSpringContextTests
并通过Foo
注释为对象@Autowire
使用依赖注入的部分。由于您正在实例化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配置是可选的,你不需要这样做。
以下是 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
更新: 如果您的项目已正确设置以进行回退,则不需要执行此操作,并且您无需执行此操作。 < / p>
这是我运行此测试时的输出:
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
===============================================