2011-10-12 8 views
11

TemporaryFolder@Ruleを使用するJUnitテストがあります。これは完璧に動作時間のほとんどJUnit @Ruleライフサイクルと@Beforeのやりとり

@Rule 
public TemporaryFolder folder = new TemporaryFolder(); 

@Before 
public void init() { 
    folder.newFile("my-file.txt"); 
} 

@Test 
public void myTest() { ... } 

:彼らは、いくつかのセットアップを実行するために@Before方法でTemporaryFolderを使用しています。しかし、SpringJUnit4ClassRunnerを使用すると、私のTemporaryFolderインスタンス内のStatementが適用される前にinit()メソッドが呼び出されることがあります。このため、folderinit()以内で使用され、ファイルが/tmpではなく作業ディレクトリにある場合、一時フォルダの場所は設定されていません(null)。

したがって、@Beforeメソッドがルールより先に実行されることがありますが、明確なパターンを確立できません。私はときどき私自身のルール実装のいくつかに似た問題を見ることがあります。

設定方法の前にルールステートメントを適用する方法はありますか?

答えて

11

JUnit 4.10では、BlockJUnit4ClassRunner(SpringJUnit4ClassRunnerのスーパークラス)は、@Beforeメソッドの前にルールが実行されるようにStatementチェーンを構築するように注意しています。 JUnitの4.10から:異なる順序で一緒に声明チェーンステッチする

protected Statement methodBlock(FrameworkMethod method) { 
    // ... 
    Statement statement= methodInvoker(method, test); 
    statement= possiblyExpectingExceptions(method, test, statement); 
    statement= withPotentialTimeout(method, test, statement); 
    statement= withBefores(method, test, statement); 
    statement= withAfters(method, test, statement); 
    statement= withRules(method, test, statement); 
    return statement; 
} 

のJUnit 4.7が表示されます:

Statement statement= methodInvoker(method, test); 
statement= possiblyExpectingExceptions(method, test, statement); 
statement= withPotentialTimeout(method, test, statement); 
statement= withRules(method, test, statement); 
statement= withBefores(method, test, statement); 
statement= withAfters(method, test, statement); 
return statement; 

春-TEST-3.0.5の親POMそれはJUnitを4.7に依存していることを示していると思われます。新しいJUnitを使うのが助けになるのではないかと思いますか?何が価値があるために

+1

好きな@pholser。私はJUnit 4.8.xを使用していますが、それは4.10と同じ順序でチェーンを構築するように見えます。ただし、me​​thodBlock()はSpringJUnit4ClassRunnerでオーバーライドされ、JUnit 4.7と同様の順序を設定します。 – teabot

0

、私は迅速な回避策として、以下を使用しました:

@Rule 
public TemporaryFolder tmpFolder = new TemporaryFolder() { 
    @Override 
    protected void before() throws Throwable { 
     if (getRoot() == null) { 
      super.before(); 
     } 
    } 

    @Override 
    public File newFile(String fileName) throws IOException { 
     try { 
      before(); 
     } 
     catch (Throwable t) { 
      throw new RuntimeException(t.getMessage(), t); 
     } 

     return super.newFile(fileName); 
    } 

    @Override 
    public File newFolder(String folderName) { 
     try { 
      before(); 
     } 
     catch (Throwable t) { 
      throw new RuntimeException(t.getMessage(), t); 
     } 

     return super.newFolder(folderName); 
    } 
}; 

これは関係なく、@Before方法は、ルールの前または後に実行されるかどうかの、TemporaryFolderが正しく初期化されていることを保証します。

関連する問題