2012-02-03 5 views
13

単体テストでは、かなり複雑な設定を行う必要があります(これはコードの匂いかもしれませんが、これはこれに関するものではありません:-)) 。私が興味を持っているのは、複数の@Beforeメソッドがセットアップを実行する方が良い場合、または1つだけヘルパメソッドを呼び出して初期化を実行する方が良い場合です。Junit - 複数前@対前@メソッドに分割する前に

など。

@Before 
public void setUpClientStub() { 

} 

@Before 
public void setUpObjectUnderTest() { 

} 

@Before 
public void setUp() { 
    setUpClientStub(); 
    setUpObjectUnderTest(); 
} 
+1

何基底クラスはどうですか?そうでなければ、メソッドに対して何の問題も見ません... – wuppi

答えて

20

他の応答で述べたように、JUnitのメソッドの検索順序は保証されていないため、@Beforeメソッドの実行順序は保証できません。同じことが@Ruleの場合も同じですが、保証の欠如があります。これが常に同じコードである場合、2つのメソッドに分割する点はありません。

2つの方法があり、もっと重要なことに、複数の場所から使用する場合は、4.10で導入されたRuleChainを使用してルールを組み合わせることができます。これは以下のような、ルールの特定の順序付けを可能にする:

public static class UseRuleChain { 
    @Rule 
    public TestRule chain= RuleChain 
       .outerRule(new LoggingRule("outer rule")) 
       .around(new LoggingRule("middle rule")) 
       .around(new LoggingRule("inner rule")); 

    @Test 
    public void example() { 
     assertTrue(true); 
    } 
} 

これが生成します。

starting outer rule 
starting middle rule 
starting inner rule 
finished inner rule 
finished middle rule 
finished outer rule 

をですから、4.10にアップグレードするか、または単にクラスを盗みます。

あなたのケースでは、クライアントセットアップ用とオブジェクト用の2つのルールを定義し、それらをRuleChainで組み合わせることができます。 ExternalResourceを使用してください。

public static class UsesExternalResource { 
    private TestRule clientRule = new ExternalResource() { 
     @Override 
     protected void before() throws Throwable { 
     setupClientCode(); 
     }; 

     @Override 
     protected void after() { 
     tearDownClientCode() 
    }; 
    }; 

    @Rule public TestRule chain = RuleChain 
        .outerRule(clientRule) 
        .around(objectRule); 
} 

だから、あなたは、次の実行順序があるでしょう:

clientRule.before() 
objectRule.before() 
the test 
objectRule.after() 
clientRule.after() 
+0

これは素晴らしい解決策ですが、読みやすさの観点からは@hvgotcodesの提案を選択しました。 – Timo

+1

メソッドが再利用されることを意図していない場合でも、メソッドにコメントを追加するのではなく、メソッドを意味のある名前にするために、メソッドを別個のメソッドとして持つことができます。 – herman

5

私は後者を行うだろう。 AFAIK、注釈付き設定方法の@前の順序を保証する方法はありません。

2

私はそれが大きな違いはないと思っていますが、私は個人的に2番目の方法を優先しています(メソッドが実行される前の順序は定義されていないので、より良いコントロールになります)。

3

@Before注釈付きメソッドが呼び出される順序は保証されません。それらの間にいくつかの依存関係がある場合(例えば、あるメソッドが他のメソッドの前に呼び出されなければならない場合)、の形式を使用する必要があります。

これ以外の場合は、これを優先して1つの場所に保管しておくと簡単に見つけることができます。

関連する問題