我有一个Spring-Boot应用程序,其中在应用程序中设置了默认属性。属性文件在类路径(src/main/resources/application.properties)。

我想用测试中声明的属性覆盖JUnit测试中的一些默认设置。属性文件(src/test/resources/test. Properties)

我通常为我的Junit测试有一个专用的配置类,例如。

package foo.bar.test;

import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;

@Configuration
@Import(CoreConfig.class)
@EnableAutoConfiguration
public class TestConfig {

}

我最初认为在TestConfig类中使用@PropertySource("classpath:test.properties")可以达到目的,但是这些属性不会覆盖应用程序。属性设置(参见Spring-Boot参考文档- 23。外部化配置)。

然后我尝试使用-Dspring.config.location=classpath:test。属性。这是成功的——但是我不想为每次测试执行都设置这个系统属性。因此我把它放在代码中

@Configuration
@Import(CoreConfig.class)
@EnableAutoConfiguration
public class TestConfig {

  static {
    System.setProperty("spring.config.location", "classpath:test.properties");
  }

}

不幸的是,这次也没有成功。

必须有一个简单的解决方案如何覆盖应用程序。使用test在JUnit测试中设置属性。我一定是忽略了这些特性


当前回答

这对我来说很管用:

我的测试:

@SpringBootTest
@TestPropertySource(properties = "spring.config.additional-location=classpath:application-test.yml")
class EngineApplicationTests {
    @Test
    void contextLoads() {
    }
}

我的版本:

plugins {
    id 'org.springframework.boot' version '2.7.1'
    id 'io.spring.dependency-management' version '1.0.12.RELEASE'
    id 'java'
}

group = 'com.kubemachine'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

ext {
    set('springCloudVersion', "2021.0.3")
}

我的gradle文件中唯一的测试依赖项:

testImplementation 'org.springframework.boot:spring-boot-starter-test'

我的身材里也有这个。gradle文件:

test {
    useJUnitPlatform()
}

和两个属性文件:

src / main /资源/ application.yml src /测试/资源/ application-test.yml

在这个设置中,应用程序测试。yml绝对只覆盖application.yml中的值。我不需要重复应用程序中的属性值。在application-test.yml。应用程序测试。Yml确实扩展了application.yml。

其他回答

另一种适用于覆盖测试中的一些属性的方法,如果你使用@SpringBootTest注释:

@SpringBootTest(properties = {"propA=valueA", "propB=valueB"})

这对我来说很管用:

我的测试:

@SpringBootTest
@TestPropertySource(properties = "spring.config.additional-location=classpath:application-test.yml")
class EngineApplicationTests {
    @Test
    void contextLoads() {
    }
}

我的版本:

plugins {
    id 'org.springframework.boot' version '2.7.1'
    id 'io.spring.dependency-management' version '1.0.12.RELEASE'
    id 'java'
}

group = 'com.kubemachine'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

repositories {
    mavenCentral()
}

ext {
    set('springCloudVersion', "2021.0.3")
}

我的gradle文件中唯一的测试依赖项:

testImplementation 'org.springframework.boot:spring-boot-starter-test'

我的身材里也有这个。gradle文件:

test {
    useJUnitPlatform()
}

和两个属性文件:

src / main /资源/ application.yml src /测试/资源/ application-test.yml

在这个设置中,应用程序测试。yml绝对只覆盖application.yml中的值。我不需要重复应用程序中的属性值。在application-test.yml。应用程序测试。Yml确实扩展了application.yml。

如果你和我一样有同样的应用。src/main/resources和src/test/resources中的属性,你想知道为什么应用程序。属性不会覆盖应用程序。属性在你的主要资源,阅读…

简单的解释:

If you have application.properties under src/main/resources and the same application.properties under src/test/resources, which application.properties gets picked up, depends on how you are running your tests. The folder structure src/main/resources and src/test/resources, is a Maven architectural convention, so if you run your test like mvnw test or even gradlew test, the application.properties in src/test/resources will get picked up, as test classpath will precede main classpath. But, if you run your test like Run as JUnit Test in Eclipse/STS, the application.properties in src/main/resources will get picked up, as main classpath precedes test classpath.

您可以通过打开菜单栏查看运行>运行配置> JUnit > *your_run_configuration* >单击“显示命令行”。

你会看到这样的东西:

XXXbin\javaw.exe -ea -Dfile。编码= UTF-8 -classpath XXX \ workspace-spring-tool-suite-4-4 5。1 .发布project_name \ bin \玩; XXX \ workspace-spring-tool-suite-4-4 5。1 .发布project_name \ bin \测试;

你看到类路径xxx\main先出现,然后是xxx\test吗?对,这都是关于类路径的:-)

附注: 注意在启动配置中覆盖的属性(例如在Spring Tool Suite IDE中)优先于application.properties。

改变顺序:

现在,在Spring中一切都是可配置的。你可以改变构建类路径,让xxx\test先出现,然后是xxx\main。

简单地转到项目>属性> Java构建路径>顺序和导出,通过将任何测试文件夹放在前面来更改构建类路径顺序,例如:

就是这样!

更好的解决方案

一个更好的解决方案是在测试时激活src/test/resources/application-{profile}。属性(其中profile可以测试),例如在src/main/resources/application.properties中:

spring.profiles.active =测试

这更整洁,并让您完全控制在做什么时激活哪个配置文件。

您可以使用@TestPropertySource来覆盖application.properties中的值。从它的javadoc:

测试属性源可用于选择性地覆盖系统和应用程序属性源中定义的属性

例如:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = ExampleApplication.class)
@TestPropertySource(locations="classpath:test.properties")
public class ExampleApplicationTests {

}
I just configured min as the following :

spring.h2.console.enabled=true
spring.h2.console.path=/h2-console


# changing the name of my data base for testing
spring.datasource.url= jdbc:h2:mem:mockedDB
spring.datasource.username=sa
spring.datasource.password=sa



# in testing i don`t need to know the port

#Feature that determines what happens when no accessors are found for a type
#(and there are no annotations to indicate it is meant to be serialized).
spring.jackson.serialization.FAIL_ON_EMPTY_BEANS=false`enter code here`