Junit TestのデフォルトのSpring-Boot application.properties設定を上書きする


198

デフォルトのプロパティがapplication.propertiesクラスパス(src / main / resources / application.properties)のファイルに設定されているSpring-Bootアプリケーションがあります。

JUnitテストのいくつかのデフォルト設定を、test.propertiesファイル(src / test / resources / test.properties)で宣言されたプロパティで上書きしたい

私は通常、Junitテスト用の専用のConfigクラスを持っています。

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 {

}

@PropertySource("classpath:test.properties")TestConfigクラスで使用するとうまくいくと最初に思いましたが、これらのプロパティはapplication.properties設定を上書きしません(Spring-Boot Reference Doc- 23. Externalized Configurationを参照)。

次に-Dspring.config.location=classpath:test.properties、テストを呼び出すときに使用してみました。これは成功しました。ただし、テストの実行ごとにこのシステムプロパティを設定したくありません。したがって、私はそれをコードに入れました

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

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

}

残念ながらこれも成功しませんでした。

application.propertiesJUnitテストの設定をオーバーライドする方法についてtest.properties、私が見落としていたはずの簡単な解決策があるはずです。


いくつかのプロパティのみを構成する必要がある場合は、新しい@DynamicPropertySourceアノテーションを使用できます。stackoverflow.com/a/60941845/8650621
Felipe Desiderati

回答:


293

を使用@TestPropertySourceして、の値を上書きできますapplication.properties。そのjavadocから:

テストプロパティソースを使用して、システムおよびアプリケーションプロパティソースで定義されたプロパティを選択的にオーバーライドできます。

例えば:

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

}

2
それでおしまい。ありがとう。残念ながら、ExampleApplication.classで使用すると機能しないため、各テストクラスで設定する必要があります。そうですか?
FrVaBe

1
これは、テストクラスの階層のどこかに移動する必要があります。つまり、共通のスーパークラスを使用して、さまざまなテストクラス全体で構成することができます。
アンディウィルキンソン

64
は、のような一部のプロパティをインラインで上書き@TestPropertySourceするproperties引数を受け入れることができることにも注意し@TestPropertySource(properties = "myConf.myProp=valueInTest")てください。まったく新しいプロパティファイルが必要ない場合に便利です。
2016

2
あなたは、アレイ内の複数のファイルを指定し、また、ファイルシステム上のファイル(彼らはCIサーバ上で動作しない場合があります覚えている)ことができます@TestPropertySource(locations={"file:C:/dev/...","classpath:test.properties"})
アダム

8
これ@SpringApplicationConfigurationはすでに非推奨であり、使用する必要があることに注意してください@SpringBootTest
mrkernelpanic 2017年

74

Spring Bootはsrc/test/resources/application.properties、次のアノテーションが使用されている場合、自動的にロードされます

@RunWith(SpringRunner.class)
@SpringBootTest

したがって、に名前test.propertiesを変更しapplication.propertiesて自動構成を利用します。

プロパティファイルを(環境に)ロードする必要があるだけの場合は、ここで説明するように、以下を使用することもできます。

@RunWith(SpringRunner.class)
@ContextConfiguration(initializers = ConfigFileApplicationContextInitializer.class) 

[ 更新:テストのために特定のプロパティを上書きする ]

  1. 追加 src/main/resources/application-test.propertiesます。
  2. テストクラスにで注釈を付け@ActiveProfiles("test")ます。

この負荷application.properties及びその後 application-test.propertiesテストケースのためのアプリケーション・コンテキストにプロパティ、定義された規則に従って、ここ

デモ-https://github.com/mohnish82/so​​-spring-boot-testprops


1
application.propertiesクラスパスに2つのファイル(1つはとsrc/main/resources1つsrc/test/resources)を置くのが良いかどうかはわかりません。どちらが採用され、どちらが最初に採用されることを誰が保証しますか?
FrVaBe 2017

3
@FrVaBe Springが保証します!メインプロファイルプロパティは常に読み込まれます。次に、テストフェーズ中に、テストプロパティが読み込まれ、新しい/既存のプロパティが追加/オーバーライドされます。同じ名前の2つのファイルを保つようにしない場合は、追加することができますapplication-test.propertiessrc/main/resourcesし、指定したtestテストケースでアクティブなプロファイルとして。
モニッシュ、2017

7
春は保証をしません。ビルドツールは、テスト中にメインリソースを優先してテストリソースを使用します。ただし、テストのapplication.propertiesの場合、メインのapplication.propertiesは無視されます。メインの値にはいくつかの有用なデフォルト値が含まれており、テスト中にそれらの一部をオーバーライドするだけでよいので、それは私が望むものではありません(そして、テストセクションでファイル全体を複製したくありません)。こちらをご覧ください
FrVaBe 2017

6
正解です。src/test/resources/application.propertiesテスト段階でに定義されたプロパティのみが読み込まれ、src/main/resources/application.properties無視されます。
モニッシュ、2017

11
これまでにプロファイルを使用しない場合は、専用の「テスト」プロファイルは必要ありません。テストプロパティに名前を付けるだけでapplication-default.properties、「デフォルト」プロファイルが自動的に実行されるため、これらは考慮されます(他に宣言されていない場合)。
FrVaBe 2017

65

メタ注釈を使用して構成を外部化することもできます。例えば:

@RunWith(SpringJUnit4ClassRunner.class)
@DefaultTestAnnotations
public class ExampleApplicationTests { 
   ...
}

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@SpringApplicationConfiguration(classes = ExampleApplication.class)
@TestPropertySource(locations="classpath:test.properties")
public @interface DefaultTestAnnotations { }

21

@SpringBootTest注釈を使用している場合、テストでいくつかのプロパティをオーバーライドするのに適した別のアプローチ:

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

1
SpringBootTestapplication.propertiesファイルをロードしますか?
TuGordoBello

8

TLDR:

だから私がやったことは、標準src/main/resources/application.propertiessrc/test/resources/application-default.properties、すべてのテストのいくつかの設定を上書きする場所を持つことでした。

全話

私は同じ問題に遭遇し、今のところプロファイルも使用していませんでした。今それをし、プロファイルを宣言することを覚えておかなければならないことは面倒であるように見えました-それは簡単に忘れられる可能性があります。

コツは、特定のプロファイルを利用してapplication-<profile>.properties、一般的なプロファイルの設定を上書きすることです。https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html#boot-features-external-config-profile-specific-propertiesを参照してください


3

簡単な説明:

あなたが私のようなもので、とに同じものapplication.propertiessrc/main/resourcesありsrc/test/resources、テストフォルダのがメインリソースのをオーバーライドしないのはなぜか疑問に思っているapplication.propertiesなら、読んでください...application.properties

あなたがapplication.propertiesアンダーsrc/main/resourcesと同じapplication.propertiesアンダーを持っている場合src/test/resources、それapplication.propertiesはピックアップされますが、テストの実行方法依存します。フォルダ構造 src/main/resourcesとはsrc/test/resources、あなたのようなテストを実行している場合は、Mavenの建築慣例であるmvnw testかさえもgradlew testと、テストクラスパスがメインクラスパスの前application.propertiessrc/test/resources来るため、in が選択されます。ただし、Elipse / STSのようにテストを実行すると、次のようにin が取得されます。Run as JUnit Testapplication.propertiessrc/main/resourcesメインクラスパスがテストクラスパスに先行ます。

あなたはそれを開くことによってそれをチェックアウトすることができます Run > Run Configurations > JUnit > *your_run_configuration* > Click on "Show Command Line"ます。

次のようなものが表示されます。

XXXbin \ javaw.exe -ea -Dfile.encoding = UTF-8 -classpath XXX \ workspace-spring-tool-suite-4-4.5.1.RELEASE \ project_name \ bin \ main; XXX \ workspace-spring-tool-suite-4-4.5.1.RELEASE \ project_name \ bin \ test;

あなたがいることがわかりますかメインは\最初に来るし、次に\テスト?そう、それはクラスパスのすべてです :-)

乾杯


1
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`

1

Spring 5.2.5およびSpring Boot 2.2.6を使用していて、ファイル全体ではなく、いくつかのプロパティのみをオーバーライドする場合。新しいアノテーションを使用できます:@DynamicPropertySource

@SpringBootTest
@Testcontainers
class ExampleIntegrationTests {

    @Container
    static Neo4jContainer<?> neo4j = new Neo4jContainer<>();

    @DynamicPropertySource
    static void neo4jProperties(DynamicPropertyRegistry registry) {
        registry.add("spring.data.neo4j.uri", neo4j::getBoltUrl);
    }
}

0

それ以外の場合は、デフォルトのプロパティ設定名を変更してプロパティを設定し、ネイティブのインスタンスのspring.config.name=testクラスパスリソース をこの分離されたtest.propertiesから自動設定して、アプリケーションプロパティを無視することができます。src/test/test.propertiesorg.springframework.boot.SpringApplication

利点:テストの自動構成。

欠点:CIレイヤーで「spring.config.name」プロパティを公開する

参照:http : //docs.spring.io/spring-boot/docs/current/reference/html/common-application-properties.html

spring.config.name = application#構成ファイル名


5
テストでは元の構成値の一部application.propertiesを上書きするだけなので、無視することは私にとって選択肢ではありません。
FrVaBe 2016年

私はsrc / main / resources / application.propertiesをロードしない単一のテストを行う方法を探していましたが、これがそれです。ファイルsrc / test / resources / empty.propertiesを作成し、メインプロパティを無視する必要があるテストに注釈を追加します。@TestPropertySource(properties = "spring.config.name = empty")
rvertigo

各junitテストメソッドに特定のプロパティ値を設定するにはどうすればよいですか?
ニコラ

0

JUnitが記述されているsrc / test / resourcesにapplication.propertiesファイルを作成することもできます。


これはどのように役立ちますか?^^
jumping_monkey
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.