web-dev-qa-db-ja.com

@ConfigurationPropertiesおよび@Autowiredを使用してクラスをテストする方法

@Autowiredおよび@ConfigurationPropertiesでロードされたプロパティに依存するアプリケーションの小さな部分をテストしたい。 ApplicationContext全体ではなく、必要なプロパティのみを読み込むソリューションを探しています。ここに縮小された例として:

@TestPropertySource(locations = "/SettingsTest.properties")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {TestSettings.class, TestConfiguration.class})
public class SettingsTest {
    @Autowired
    TestConfiguration config;

    @Test
    public void testConfig(){
        Assert.assertEquals("TEST_PROPERTY", config.settings().getProperty());
    }
}

構成クラス:

public class TestConfiguration {
    @Bean
    @ConfigurationProperties(prefix = "test")
    public TestSettings settings (){
        return new TestSettings();
    }
}

設定クラス:

public class TestSettings {
    private String property;

    public String getProperty() {
        return property;
    }

    public void setProperty(String property) {
        this.property = property;
    }
}

リソースフォルダーのプロパティファイルには、エントリが含まれています。

test.property=TEST_PROPERTY

私の現在の設定では、configはnullではありませんが、使用可能なフィールドはありません。フィールドがフィールドではない理由は、SpringbootではなくSpringを使用しているという事実と関係があるはずです。では、これを実行するSpringbootの方法は何でしょうか?

編集:これを行う理由は、Textfileを解析するパーサーがあり、使用される正規表現がプロパティファイルに保存されているためです。これをテストするには、このパーサーに必要な、TestSettingsの上にあるプロパティのみをロードします。

コメントを読んでいる間、私はすでにこれが単体テストではないことに気づきました。しかし、この小さなテストに完全なSpringブート構成を使用することは、私には少し多すぎるように思えます。そのため、プロパティを持つクラスを1つだけロードする可能性があるかどうかを尋ねました。

27
IndianerJones

いくつかのポイント:

  1. メインパッケージに「TestConfiguration」クラスは必要ありません。これは、「TestSettings」Beanを構成するだけだからです。 TestSettingsクラス自体に注釈を付けるだけでこれを行うことができます。

  2. 通常は、テストに必要なコンテキストを@ SpringApplicationConfigurationアノテーションを使用してロードし、Applicationクラスの名前を渡します。ただし、ApplicationContext全体をロードする必要はないと述べたため(理由は明らかではありませんが)、テスト専用のロードを行うには特別な構成クラスを作成する必要があります。以下では、元々持っていたTestConfigurationクラスとの混乱を避けるために、「TestConfigurationNew」と呼びます。

  3. Spring Bootの世界では、すべてのプロパティは通常「application.properties」ファイルに保持されます。しかし、それらを他の場所に保存することは可能です。以下に、あなたが提案した「SettingsTest.properties」ファイルを指定しました。このファイルの2つのコピーを作成できることに注意してください。1つはmain/resourcesフォルダーにあり、もう1つはtest/resourcesフォルダーにあります。

コードを次のように変更します。

TestSettings.Java(メインパッケージ内)

@Configuration
@ConfigurationProperties(prefix="test", locations = "classpath:SettingsTest.properties")
public class TestSettings {

    private String property;

    public String getProperty() {
        return property;
    }

    public void setProperty(String property) {
        this.property = property;
    }
}

SettingsTest.Java(テストパッケージ内)

@TestPropertySource(locations="classpath:SettingsTest.properties")
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestConfigurationNew.class)
public class SettingsTest {

    @Autowired
    TestSettings settings;

    @Test
    public void testConfig(){
        Assert.assertEquals("TEST_PROPERTY", settings.getProperty());
    }
}

TestConfigurationNew.Java(テストパッケージ内):

@EnableAutoConfiguration
@ComponentScan(basePackages = { "my.package.main" })
@Configuration
public class TestConfigurationNew {
}

これで、希望どおりに動作するはずです。

15
David H

次のように、TestConfiguraionに@EnableConfigurationPropertiesの注釈を付ける必要があります。

@EnableConfigurationProperties
public class TestConfiguration {

    @Bean
    @ConfigurationProperties(prefix = "test")
    public TestSettings settings (){
        return new TestSettings();
    }
}

また、TestConfiguration.classをあなたの@ContextConfigurationに含める必要があるのはSettingsTestクラスのみです:

@TestPropertySource(locations = "/SettingsTest.properties")
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = TestConfiguration.class)
public class SettingsTest {
...
24
Stepan Kolesnik

実際には、@ EnableConfigurationPropertiesを@SpringBootTestに直接追加するだけです。
例えば:

@ActiveProfiles("test")
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfiguration.class)
@EnableConfigurationProperties
...
4
Jason

Spring Bootを使用する場合、必要なものは次のとおりです。

_@RunWith(SpringRunner.class)
@SpringBootTest
_

追加の_@ContextConfiguration_はありません。EnableAutoConfigurationおよびEnableConfigurationPropertiesに対するテスト専用の追加クラスはありません。ロードする構成クラスを指定する必要はありません。それらはすべてロードされます。

しかし、_main/resources/application.yml_で読みたいプロパティエントリが_test/resources/application.yml_にも存在することを確認してください。繰り返しは避けられません。


別の方法は次のとおりです。

  1. 同じレベルの_MyApplicationTest.Java_とともに、テス​​ト専用の構成クラスを定義します。このクラスは空にすることができます。

のような:

_@EnableAutoConfiguration
@EnableConfigurationProperties(value = {
        ConnectionPoolConfig.class
})
public class MyApplicationTestConfiguration {
}
_
  1. そして、自動配線された構成をロードするクラスで。

のような:

_@RunWith(SpringRunner.class)
//@SpringBootTest // the first, easy way
@ContextConfiguration(classes = MyApplicationTestConfiguration.class,
        initializers = ConfigFileApplicationContextInitializer.class)
public class ConnectionPoolConfigTest {

    @Autowired
    private ConnectionPoolConfig config;
_

基本的に、あなたは:

  • _@EnableConfigurationProperties_および_@EnableAutoConfiguration_に特定の構成を使用して、ロードする_@ConfigurationProperties_ファイルをすべてリストします
  • テストクラスでは、_application.yml_ファイルをロードするためにSpringによって定義された初期化クラスを使用して、このテストの構成ファイルをロードします。

そして、ロードする値を_test/resources/application.yml_に入れます。繰り返しは避けられません。別のファイルをロードする必要がある場合は、@TestProperties()を場所とともに使用します。 :_@TestProperties_は_.properties_ファイルのみをサポートします。


両方の方法は、構成クラスのロード値に対して機能します

  • _application.yml_/_application.properties_から
  • または、@PropertySource(value = "classpath:threadpool.properties")のようなPropertySourceで指定された別のプロパティファイルから

here によるSpring docの最後のメモ

Project Lombokを使用してゲッターとセッターを自動的に追加する人もいます。オブジェクトをインスタンス化するためにコンテナによって自動的に使用されるため、Lombokがそのようなタイプの特定のコンストラクターを生成しないことを確認してください。

最後に、標準のJava Beanプロパティのみが考慮され、静的プロパティのバインドはサポートされていません。

しかし、ここで「特定のコンストラクター」が何を意味するのかよくわかりません。

0
WesternGun