2016-09-01 6 views
4

私は、SpringコンポーネントのPowerMock @PrepareForTest注釈を使用しているSpring統合テストで特定のクラス(MyTestとしましょう)を持っています:@PrepareForTest(MyComponent.class)。これは、PowerMockがいくつかの変更を加えてこのクラスをロードすることを意味します。問題は、私の@ContextConfigurationがスーパークラスに定義されており、これはMyTestで拡張され、ApplicationContextは異なるテストクラス間でキャッシュされるということです。今すぐMyTestが実行された場合、PowerMockのバージョンはMyComponentになりますが、そうでない場合、@PrepareForTestなしで別のテスト用にコンテキストがロードされるため、テストは失敗します。テストクラスの前後でApplicationContextをダーティにします

私がしたいことは、MyTestの前に自分のコンテキストをリロードすることです。私も、このテストが行​​われた後、コンテキストをリロードしたい場合、私は

@DirtiesContext(classMode = DirtiesContext.ClassMode.BEFORE_CLASS) 

しかし、何を経由していることを行うことができますか?だから私はPowerMockの修正なしで再びMyComponentを清潔にするでしょう。 BEFORE_CLASSAFTER_CLASSの両方を実行する方法はありますか?今の

I以下のハックでそれをやった:MyTestというの

@FixMethodOrder(MethodSorters.NAME_ASCENDING) 

、その後

/** 
* Stub test to reload ApplicationContext before execution of real test methods of this class. 
*/ 
@DirtiesContext(methodMode = DirtiesContext.MethodMode.BEFORE_METHOD) 
@Test 
public void aa() { 
} 

/** 
* Stub test to reload ApplicationContext after execution of real test methods of this class. 
*/ 
@DirtiesContext(methodMode = DirtiesContext.MethodMode.AFTER_METHOD) 
@Test 
public void zz() { 
} 

それを行うにはきれいな方法があるかどうか、私は疑問に思って?

別の質問として、完全なコンテキストではなく特定のBeanのみをリロードすることは可能ですか?

+0

なぜあなたは*試験前ダーティコンテキスト*をマークしたいですか? – Raedwald

+0

私は@PrepareForTest(MyComponent.class)が動作するように、MyTestクラスのコンテキストをリロードしたいと思います。 – dty

答えて

7

BEFORE_CLASSとAFTER_CLASSの両方を行う方法はありますか?

いいえ、残念ながら@DirtiesContextでサポートされていません。

しかし、MyTestの新しいApplicationContextは、親テストクラスのコンテキストと同じですが、MyTestの間だけ有効です。そして、あなたは親のテストクラスのためにキャッシュされたコンテキストに影響を与えたくありません。

だから、トリックを実行する必要があります。 @DirtiesContext

@RunWith(SpringJUnit4ClassRunner.class) 
// Inherit config from parent and combine with local 
// static Config class to create a new context 
@ContextConfiguration 
@DirtiesContext 
public class MyTest extends BaseTests { 

    @Configuration 
    static class Config { 
     // No need to define any actual @Bean methods. 
     // We only need to add an additional @Configuration 
     // class so that we get a new ApplicationContext. 
    } 
} 

代替あなたはコンテキストが後と前にテストクラスを両方を汚さしたい場合は、まさにそのカスタムTestExecutionListenerを実装することができます。たとえば、次のようにしてトリックを行います。次のように、その後、MyTestでカスタムリスナーを使用することができます

import org.springframework.core.Ordered; 
import org.springframework.test.annotation.DirtiesContext.HierarchyMode; 
import org.springframework.test.context.TestContext; 
import org.springframework.test.context.support.AbstractTestExecutionListener; 

public class DirtyContextBeforeAndAfterClassTestExecutionListener 
     extends AbstractTestExecutionListener { 

    @Override 
    public int getOrder() { 
     return Ordered.HIGHEST_PRECEDENCE; 
    } 

    @Override 
    public void beforeTestClass(TestContext testContext) throws Exception { 
     testContext.markApplicationContextDirty(HierarchyMode.EXHAUSTIVE); 
    } 

    @Override 
    public void afterTestClass(TestContext testContext) throws Exception { 
     testContext.markApplicationContextDirty(HierarchyMode.EXHAUSTIVE); 
    } 

} 

。サイドの質問として

import org.springframework.test.context.TestExecutionListeners; 
import org.springframework.test.context.TestExecutionListeners.MergeMode; 

@TestExecutionListeners(
    listeners = DirtyContextBeforeAndAfterClassTestExecutionListener.class, 
    mergeMode = MergeMode.MERGE_WITH_DEFAULTS 
) 
public class MyTest extends BaseTest { /* ... */ } 

、それだけで、特定の豆ではなく、完全なコンテキストをリロードすることは可能でしょうか?

いいえ、それもできません。

よろしく、

サム(春TestContextフレームワーク著者)

+0

ご返信ありがとうございます。 '親テストクラスのコンテキストと同じMyTest用の新しいApplicationContextが必要です'これは真ではありません。MyTestのコンテキストは '@PrepareForTest(MyComponent.class)'を使うべきなので完全に同じではないからです。私はあなたの提案を試みたが、別の問題が発生した。私が理解しているように、2つのコンテキストが並行して存在しますが、現時点では不可能です(Hazelcastインスタンスが設定されており、1つのポートに1つしか存在しない場合があります)。私はそれに対処することができるので、私はこのネストされたコンテキストでPowemockアノテーションを動作させる方法が不思議です。 – dty

+0

私はテストクラスの前後にコンテキストを汚すカスタム 'TestExecutionListener'を追加して答えを更新しました。それがあなたの問題を解決するかどうか教えてください。 –

+0

うん、それは、ハックよりもはるかに良いように見える:)ありがとう! – dty

関連する問題