SpringBoot 1.5+ junit测试不会使用自定义名称加载配置

时间:2018-06-01 08:46:11

标签: java spring spring-boot junit

我正在设置spring boot应用程序,我希望使用自定义文件名来配置而不是application.yml。原因是运行这些应用程序的服务器端tomcat。

我定义了应用程序类:

@SpringBootApplication(scanBasePackages={"com.example"})
public class Application extends SpringBootServletInitializer {
    public static void main(String[] args) {
        System.setProperty("spring.config.name", "myapp");
        SpringApplication.run(Application.class, args);
    }
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.properties("spring.config.name: myapp").sources(Application.class);
    }
    ...

配置名为myapp.yml

在JUnit测试中,我有以下注释:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = {Application.class})
@ContextConfiguration(initializers = {ConfigFileApplicationContextInitializer.class})
@AutoConfigureMockMvc
public class UserTest {
...

和junit的pom依赖关系:

    <dependency>
        <groupId>org.jmockit</groupId>
        <artifactId>jmockit</artifactId>
        <version>1.31</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-module-junit4</artifactId>
        <version>1.7.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.powermock</groupId>
        <artifactId>powermock-api-mockito</artifactId>
        <version>1.7.3</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>1.5.3.RELEASE</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <version>RELEASE</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.restdocs</groupId>
        <artifactId>spring-restdocs-mockmvc</artifactId>
        <version>RELEASE</version>
        <scope>test</scope>
    </dependency>
<!-- if I remove this dependency then normal application works with custom name but if I have it in dependencies then mvn spring-boot:run does not find configuration either -->
    <dependency>
        <groupId>org.yaml</groupId>
        <artifactId>snakeyaml</artifactId>
        <version>RELEASE</version>
        <scope>test</scope>
    </dependency>

我尝试过很多不同的东西,但是我无法按照自己的意愿去做。我想要自己的文件名进行配置,然后使用@ActiveProfiles注释解决不同的配置。谢谢!

2 个答案:

答案 0 :(得分:1)

正如@ M.Deinum所提到的,你应该在测试类的@BeforeClass方法中初始化属性:

param(
[string]$currentEnv
)

[object]$paramObj=Get-Content "d:\a\r1\a\Jobs\WebJobs_scripts\WebJob_list.json" |ConvertFrom-Json
$userName =$paramObj.$currentEnv
$password =$paramObj.$currentEnv
$webAppName =$paramObj.$currentEnv
$resourceGroup=$paramObj.$currentEnv
[object[]]$webJobs=$paramObj.$currentEnv.webJobs
foreach($wj in $webjobs)
{
  if($wj.typeName -eq "continuous")
   {
    Invoke-AzureRmResourceAction -ResourceGroupName $resourceGroup -ResourceType Microsoft.Web/sites/ContinuousWebJobs -ResourceName "$webAppName/$($wj.name)" -Action stop -ApiVersion 2015-08-01 -Force
    Write-Host "continuous"
    Write-Host $wj.name
   }
}

良好的做法是在测试后整理属性,以便其他测试不受这些属性的影响

@BeforeClass
public static void initProperties() {
    System.setProperty("spring.config.name", "myapp"); 
}

但是有更好的选择使用测试属性:

您也应该在测试中使用application.yaml。您的动态配置(例如数据库凭据)不应放在此配置文件中。它们应该通过env属性传递给应用程序(因此12 factor app principles)。

在测试期间,有多种方法可以定义此动态配置。 E.g:

  1. 使用上述机制@AfterClass public static void clearProperties() { System.clearProperty("spring.config.name"); } + @BeforeClass
  2. 或者您可以通过System.setPRoperty注释或@TestProperties属性
  3. 使用其他测试配置文件

答案 1 :(得分:0)

假设您有名为application-test.yml的自定义配置,而不是application.yml

您只需要在测试类中添加以下内容,

@SpringBootTest(value={"spring.profiles.active=test"})

这样您就可以避免设置配置属性,并再次专门在@BeforeTest@AfterTest中重置它们。

希望它有所帮助!