10

junit 4 の「パラメーター化」機能を使用していますが、@parameters メソッドが @beforeclass メソッドの前に実行されることに気付きました。@parameters を介してテストケースに渡すパラメーターは @beforeclass メソッドで初期化するコードに依存するため、これは私にとって問題を引き起こしています。例えば

@RunWith(Parameterized.class)
public class TestOtherClass {

    String argument;
    private static boolean initializeThis;

    public TestOtherClass(String parameter) throws Exception {
        argument=parameter;
    }

    @BeforeClass
    public static void doSetup() {
        System.out.println("Doing setup before class...");
        initializeThis=true; // true or false, based on some condition
    }

    @Test
    public void otherTest() {
        System.out.println("Other test: " + argument);
    }

    @Parameters
    public static Collection<Object[]> getData(){
        System.out.println("Inside parameter");
        String addThis;
        if(initializeThis)
            addThis="adding true";
        else
            addThis="adding false";

        Object[] para1 = new Object[]{"First parameter :: " + addThis};
        Object[] para2 = new Object[]{"Second parameter :: " + addThis};

        Collection<Object[]> classNames = new ArrayList<Object[]>();
        classNames.add(para1);
        classNames.add(para2);
        return classNames;
    }
}

今、@beforeclassメソッドで変数「initializeThis」をtrueに初期化していますが、(驚くべきことに)テストケースを実行すると出力されます

Other test: First parameter :: adding false
Other test: Second parameter :: adding false

それは予想外のことです。
私の質問は; @parametersの前に@beforeclassメソッドを実行する方法はありますか?これはjunit 4で実行できますか?

4

4 に答える 4

6

@BeforeClass の代わりに単純な古い Java static {..} イニシャライザを使用します。

@RunWith(Parameterized.class)
public class TestOtherClass {

    String argument;
    private static boolean initializeThis;

    public TestOtherClass(String parameter) throws Exception {
        argument=parameter;
    }

    static {
        doSetup();
    }

    // @BeforeClass
    public static void doSetup() {
        System.out.println("Doing setup before class...");
        initializeThis=true; // true or false, based on some condition
    }

    @Test
    public void otherTest() {
        System.out.println("Other test: " + argument);
    }

    @Parameters
    public static Collection<Object[]> getData(){
        System.out.println("Inside parameter");
        String addThis;
        if(initializeThis)
            addThis="adding true";
        else
            addThis="adding false";

        Object[] para1 = new Object[]{"First parameter :: " + addThis};
        Object[] para2 = new Object[]{"Second parameter :: " + addThis};

        Collection<Object[]> classNames = new ArrayList<Object[]>();
        classNames.add(para1);
        classNames.add(para2);
        return classNames;
    }
}

私が知っている唯一の欠点は、これから継承されたクラスが静的初期化子をオーバーライドできないことですが、 @BeforeClass はこの側面である程度の自由を与えます。

于 2013-02-20T14:40:54.407 に答える
4

これは古い質問ですが、最近同じ問題がありました。@Parameters メソッドで @BeforeClass メソッドを呼び出すという最も明白な回避策に対応するソリューションはないように思われます。後者は静的で、テストが実行される前に一度だけ実行されます。したがって、@BeforeClass メソッドとして注釈が付けられていなくても、すべての意図と目的のために @BeforeClass メソッドです。詳細については、http: //feraldeveloper.blogspot.co.uk/2013/12/beforeclass-and-parametrized-junit-tests.htmlを参照してください。

于 2013-12-28T22:15:17.167 に答える
1

JUnit はRunner、パラメーター リスト内の各項目に対して を作成します。a はRunner、テスト メソッドをカプセル化するものです。したがって、@Parametersは常に @BeforeClass の前に実行されます。

ただし、 @Parameterized とAssumeを組み合わせることができます。実行するかどうかに関係なく、常にすべてのパラメーターをリストに含めます。assumeTrue()次に、テスト メソッドで、値に対する which テストを追加しinitializeThisます。

@RunWith(Parameterized.class)
public class TestOtherClassAssume {
  private final String argument;
  private final boolean initializeThisTest;
  private static boolean initializeThis;

  @Parameters
  public static Collection<Object[]> getData(){
    System.out.println("Inside parameter");

    return Arrays.asList(new Object[][] {
      { false, "First" },
      { true, "Second" },
    });
  }

  public TestOtherClassAssume(boolean initializeThisTest, String argument) {
    this.initializeThisTest = initializeThisTest;
    this.argument = argument;
  }

  @BeforeClass
  public static void doSetup() {
    System.out.println("Doing setup before class...");
    initializeThis = true; // true or false, based on some condition
  }

  @Test
  public void otherTest() {
    Assume.assumeTrue(initializeThis == initializeThisTest);
    System.out.println("Other test: " + argument);
  }
}

これからの出力は次のとおりです。

Inside parameter
Doing setup before class...
Other test: Second
于 2012-07-11T13:46:47.327 に答える