2012-04-22 20 views
3

Junitルールを特定のテストにのみ適用することはできますか?もしそうなら、どうしたらいいですか?特定のテストに適用するJUnitルールを設定する方法

以下のコードは、私が@Ruleを使用するたびに、それを実行するために注釈が付けられた特定のルールを持つメソッドを下にしたいと考えています。私はそのルールを対応するテストで実行したいだけです。私は他のテストがルールの影響を受けることを望まない。

この場合、これらのテストを実行すると、EmptyFileCheckのテストの1つで、ファイルDNEが存在しないことがわかりますが、その関数に別のアノテーションを使用していたため、別のコンテキストで実行し、Emptyを提供しますが、代わりにDNEが使用されます。

import static java.lang.System.in; 
import static java.lang.System.setIn; 
import static org.junit.Assert.fail; 

import java.io.BufferedOutputStream; 
import java.io.BufferedReader; 
import java.io.ByteArrayInputStream; 
import java.io.FileNotFoundException; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.io.PipedInputStream; 
import java.io.PipedOutputStream; 
import java.io.PrintStream; 
import java.nio.channels.Pipe; 

import static org.hamcrest.core.AllOf.allOf; 

import org.hamcrest.Matcher; 
import org.hamcrest.core.AllOf; 
import static org.hamcrest.Matchers.*; 
import org.hamcrest.text.StringContains; 
import org.hamcrest.text.StringEndsWith; 
import org.hamcrest.text.StringStartsWith; 
import org.jmock.Expectations; 
import org.jmock.Mockery; 
import org.jmock.lib.legacy.ClassImposteriser; 
import org.junit.After; 
import org.junit.Before; 
import org.junit.Rule; 
import org.junit.Test; 
import org.junit.contrib.java.lang.system.TextFromStandardInputStream; 
import org.junit.runner.RunWith; 

public class UnitTests { 
    private Mockery context = new Mockery() {{ 
     setImposteriser(ClassImposteriser.INSTANCE); 
    }}; 
    private main mn; 
    private InputStream oldIn; 
    private PrintStream oldOut; 
    private InputStream mockIn; 
    private InputStreamReader mockinputStream; 
    private PrintStream mockOut; 
    private BufferedReader reader; 
    private Expectations exp; 


    @Before 
    public void setMinimalMockingExpectations() throws IOException { 
     exp = new Expectations() {{ }}; 
     mn = context.mock(main.class); 
     mockinputStream = context.mock(InputStreamReader.class); 
     oldIn = System.in; 
     oldOut = System.out; 
     mockIn = context.mock(InputStream.class); 
     mockOut = context.mock(PrintStream.class); 
     System.setOut(mockOut); 
    } 

    public void configureExpectations(boolean fileOrInput, boolean verbosity) { 
     exp.one(mockOut).println("Do you want to process standard (I)nput, or a (F)ile? I/F"); 
     if (fileOrInput) { //it's a file 
      exp.one(mockOut).println("Enter filename: "); 
     } else { //it's not 

     } 
    } 

    @After 
    public void reset() { 
     System.setOut(oldOut); 
    } 

    @Rule 
    public final TextFromStandardInputStream FileNotFoundException 
     = new TextFromStandardInputStream("F\nDNE\n"); 
    @Test(expected=FileNotFoundException.class) 
    public void EnsureFileCheckExists() throws IOException { 
     final String fileName = "DNE"; 
     configureExpectations(true, false); 
     exp.one(mn).checkFile(fileName); 
     context.checking(exp); 
     mn.main(null); 
    } 

    @Rule 
    public final TextFromStandardInputStream FileReadAccessDenied 
     = new TextFromStandardInputStream("F\nUnderPriviledged\n");:w 

    @Test(expected=FileNotFoundException.class) 
    public void FileReadAccessDenied() throws java.io.FileNotFoundException { 
     final String fileName = "UnderPriviledged"; 
     configureExpectations(true, false); 
     //exp.oneOf(mn).checkFile(with()); TODO: fix ME! 
     context.checking(exp); 
     mn.main(null); 
    } 

    @Rule 
    public final TextFromStandardInputStream EmptyFileCheck 
     = new TextFromStandardInputStream("F\nEmpty\n"); 
    @Test 
    public void EmptyFileCheck() throws java.io.FileNotFoundException { 
     final String fileName = "Empty"; 
     configureExpectations(true, false); 
     exp.one(mn).checkFile(fileName); 
     context.checking(exp); 
     mn.main(null); 
    } 
} 
+0

[Junitルールについてはこの記事で説明](http://www.singhajit.com/junit-rules/) –

答えて

2

だけ@rule注釈の外にコードを取得し、試験体の先頭に移動しない任意の理由は?

+0

これは良い方法ではありません。なぜなら、すべてのテストの開始時にコードを複製しているからです。はい、あなたはそれを多くの機能の中に置くことさえできますが、それはダウンロードできるサードパーティーのユーティリティーとして最もよく機能し、したがって変更する必要があります。その場合、コードの再利用性が最大化されます。私があなたが提案したことが間違いなく私の問題を解決することは認めていますが。 –

+1

テスト本体の中に複製されたコードは、テスト本体の直前に複製されたコードとまったく同じですか?両方とも、ステップごとに書かれたテストステップに固有のものと、別々の機能、オブジェクトまたはパッケージですべてのテストステップに共通するもので終わります。どちらのソリューションも同じように再利用可能で、ダウンロード可能です。 – soru

+0

はい、他のコードを変更する権限はありません。プラス、私はすでに私のテストを書いています。私はあなたが言ったことをしただろうが、私はすることはできません... それは、私はそれについて考えて今、あなたがポイントだと私はあなたのやり方を見て、私はあるクラスのテスト。しかし、私はすでに仕事をしてきました。クラスプロジェクトのために、私は注目に値しないと思っています。そう、ええ、私はそれをリファクタリングすべきでしたが、私は怠け者です、それはすでに完了です。 –

2

ルールには、ルールで呼び出された最初のものがあります。 ExpectedExceptionからこのような何か、:

// These tests all pass. 
public static class HasExpectedException { 
    @Rule 
    public ExpectedException thrown= ExpectedException.none(); 

    @Test 
    public void throwsNothing() { 
     // no exception expected, none thrown: passes. 
    } 

    @Test 
    public void throwsNullPointerException() { 
     thrown.expect(NullPointerException.class); 
     throw new NullPointerException(); 
    } 

    @Test 
    public void throwsNullPointerExceptionWithMessage() { 
     thrown.expect(NullPointerException.class); 
     thrown.expectMessage("happened?"); 
     thrown.expectMessage(startsWith("What")); 
     throw new NullPointerException("What happened?"); 
    } 
} 
+0

文字列引数とリフレクションを使用して、実行前に関数が一致することを確認できますか?それ? –

関連する問題