2016-10-28 23 views
4

をテストし、私はJUnitの中でこのような何かをしたいと思います:継承(または代替)

@Runwith(Parameterized.class) 
public abstract class BaseTest { 

    protected abstract List<Object[]> extraParams(); 
    protected abstract ClassUnderTest testObject; 

    @Parameters 
    public Collection<Object[]> data() { 
     List<Object> params = ...; // a standard set of tests 
     params.addAll(extraParams()); 
     return params; 
    } 

    @Test 
    public doTest() { 
     // assert things about testObject 
    } 
} 

public class ConcreteTest extends BaseTest { 
    protected ClassUnderTest = new ConcreteClass(...); 
    protected List<Object[]) extraParams() { 
     List<Object> extraParams = ...; // tests specific to this concrete type 
     return extraParams; 
    } 
} 

このクラスを拡張することで、私は下のオブジェクトに対して標準テストの束を実行するようにするためテスト、およびコンクリートクラスで指定された余分なものを加えたものです。

しかし、jUnitでは、@Parametersメソッドが静的であることが必要です。他にどのようにして、標準的なパラメタとコンクリートクラスの余分なパラメタのセットを持たせることができますか?

私がこれまでに作ってみた最高のは抽象クラスで非注釈付きCollection<Object[]> standardParams()を持つこと、およびサブクラスがメソッドが含まれていることを要求することです:

@Parameters 
public Collection<Object[]> data() { 
    List<Object> params = standardParams(); 
    params.addAll(...); // extra params 
    return params; 
} 

...しかし、このISNそれはサブクラスの作家にあまりにも多くの責任を課すので、私が望むように整頓してはいけません。

+0

スリム:あなたは私の答えを見ていることはできますか? – developer

+0

@javaguyごめんなさい、それは週末だった。 – slim

答えて

2

JUnitは@Parametersメソッドが静的でなければならないと予想し、静的メソッドを提供しない場合はNo public static parameters method on class Exceptionをスローします。

しかし、あなたの要件は以下のようにorg.junit.rules.TestRuleを実装することにより、をacheivedすることができます。

BaseTestクラス

public abstract class BaseTest { 

    @Rule 
    public MyBaseTestRule myProjectTestRule = new MyBaseTestRule(data()); 

    protected abstract List<Object[]> extraParams(); 

    public List<Object[]> data() { 
     List<Object[]> listTotal = new ArrayList<>(); 
     listTotal.addAll(extraParams()); 
     //add your base test data here 
     return listTotal; 
    } 

    public abstract List<Object[]> extraParams(); 
} 

ConcreteTestクラス

public class ConcreteTest extends BaseTest { 

    @Override 
    public List<Object[]> extraParams() { 
     List<Object[]> list = ...//set up data here 
     return list; 
    } 

    @Test 
    public void test1() { 
     Object[] testData = myProjectTestRule.getTestData(); 
     //use the test data for the test 
     //Example: Assume addition of two integers scenario and data 
     //data[0] expectedresult, data[1],[2] inputs 
     //Assert.assertEquals((int)data[0], (int)(data[1]+data[2])); 

    } 

    //add other test cases 
} 

MyBaseTestRuleクラス:

import java.util.List; 

import org.junit.rules.TestRule; 
import org.junit.runner.Description; 
import org.junit.runners.model.Statement; 

public class MyBaseTestRule implements TestRule { 

    private final List<Object[]> totalTestData; 

    private final int totalTestsSize; 

    private int currentTestIndex; 

    public MyProjectTestRule(List<Object[]> list) { 
     this.totalTestsSize = list.size(); 
     this.totalTestData = list; 
    } 

    public Object[] getTestData(){ 
     return totalTestData.get(currentTestIndex); 
    } 

    @Override 
    public Statement apply(Statement stmt, Description desc) { 

     return new Statement() { 

     @Override 
     public void evaluate() throws Throwable { 
      for(int i=0; i<totalTestsSize; i++) { 
       currentTestIndex = i; 
       stmt.evaluate(); 
      } 
     } 
     }; 
    } 
} 
+0

ありがとうございます。私が正しく理解すれば、 '@RunWith(Parameterized.class)'を使うのではなく、 "同じテストを繰り返し実行する"フレームワークを独自に実装しています。しかし 'evaluate()'が実行されるたびに 'data()'のどの項目が使われるかを '@ Test'メソッドがどのように知っているかを説明できますか? – slim

+0

@slimあなたの助けがあれば、私の答えを受け入れることができますか? – developer

+0

誰かが再発明を必要としないものを思いついた場合に備えて、私は1週間与えている。怒らないでください。私は時には、よりうまくいくものがある場合に備えて、私の答えを受け入れるのが面倒なことを人々に伝えなければならない。 – slim

関連する問題