ProfileResolverを使用しているため、テストクラスの1つのメソッド内のapplicationContextでアクティブなSpringプロファイルを変更する必要があります。変更するには、コンテストを更新する前に1行のコードを実行する必要があります。私は以下を試しました:
@WebAppConfiguration
@ContextConfiguration(locations = {"/web/WEB-INF/spring.xml"})
@ActiveProfiles(resolver = BaseActiveProfilesResolverTest.class)
public class ControllerTest extends AbstractTestNGSpringContextTests {
@Test
public void test() throws Exception {
codeToSetActiveProfiles(...);
((ConfigurableApplicationContext)this.applicationContext).refresh();
... tests here ...
codeToSetActiveProfiles(... back to prior profiles ...);
... ideally refresh/reload the context for future tests
}
}
しかし、私は得ます:
Java.lang.IllegalStateException: GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once
DirtiesContextは、クラス/メソッドの実行前ではなく実行後に実行されるため機能しません。更新/再ロードを実行する前にコード行を実行する必要があります。
助言がありますか?実行中のリスナー/フックを調べてみましたが、この動作を実現するために自分自身を挿入する明確な場所が見つかりませんでした。
設計上、ApplicationContext
のプログラムによる更新は、Spring TestContext Frameworkでは明示的にサポートされていません。さらに、テストメソッドがコンテキストを更新することは意図されていません。
したがって、リフレッシュの必要性を再評価し、別のアクティブプロファイルのセットを必要とするテストメソッドを専用のテストクラスに配置するなどの代替案を検討することをお勧めします。
要約すると、@ActiveProfiles
はdeclarative構成(value
およびprofiles
属性を介して)およびprogrammaticテスト用のアクティブプロファイルの構成(resolver
属性を介して)。ただし、メソッドレベルではなくテストクラスレベルでのみ。別のオプションは、ApplicationContextInitializer
を実装し、@ContextConfiguration(initializers=...)
を介して構成することです。
ApplicationContext
beforeに影響を与える他の唯一の方法は、SmartContextLoader
を実装するか、提供されたクラスの1つを拡張して@ContextConfiguration(loader=...)
。たとえば、AbstractGenericContextLoader.customizeContext()
を使用すると、ローダーによって作成されたGenericApplicationContext
をカスタマイズできます後Bean定義がロードされますコンテキストですが、beforeコンテキストが更新されます。 "
宜しくお願いします、
Sam(Spring TestContext Frameworkの作者)
コンテキストの更新をトリガーする素敵な小さなハックがあります-org.springframework.cloud.context.refresh.ContextRefresher
を使用することです。
この方法が適しているかどうかは100%わかりません。必須spring-cloud-context
依存関係。ただし、これはtest
依存関係として追加され、本番クラスパスにリークしない場合があります。
このリフレッシャーを使用するには、org.springframework.cloud.autoconfigure.RefreshAutoConfiguration
構成もインポートする必要があります。これにより、RefreshScope
スコープがapplicationContext
に追加され、実際に内部でジョブが実行されます。
したがって、次のようにテストを変更します。
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration;
import org.springframework.cloud.context.refresh.ContextRefresher;
// your other imports
@WebAppConfiguration
@ContextConfiguration(locations = {"/web/WEB-INF/spring.xml"}, classes = RefreshAutoConfiguration.class)
@ActiveProfiles(resolver = BaseActiveProfilesResolverTest.class)
public class ControllerTest extends AbstractTestNGSpringContextTests {
@Autowired
private ContextRefresher contextRefresher;
@Test
public void test() throws Exception {
// doSmth before
contextRefresher.refresh();
// context is refreshed - continue testing
}
}
すべてのアプリケーションコンテキストが複数のrefresh
をサポートするわけではありません。 AbstractRefreshableApplicationContext
のjavadocによると、そのサブクラスまたはAbstractRefreshableWebApplicationContext
のサブクラスのみがrefresh
を2回以上受け入れます...およびGenericApplicationContext
はそれらの1つではありません。
ホットリフレッシュをサポートするには、ApplicationContext
に別のクラスを使用する必要があります。
編集:
@ContextConfiguration
アノテーションを使用しているので、カスタムのContextLoader
またはSmartContextLoader
実装を使用して、Springがより愚かでないApplicationContext
を使用するように強制する必要があります。しかし、そのためのクリーンできちんとした方法を見つけることはできませんでした。したがって、テストクラスでXmlWebApplicationContext
が必要な場合は、@ContextConfiguration
を使用せず、手作業でコンテキストを作成して更新します@Before
メソッド内またはテストの開始時。
これは実際にはあなたの質問に答えるものではありませんが、回避策として見ることができます。