11

異なるインターフェース実装に対して同じJUnitテストを実行したいと思います。@Parameterオプションで素晴らしい解決策を見つけました:

public class InterfaceTest{

  MyInterface interface;

  public InterfaceTest(MyInterface interface) {
    this.interface = interface;
  }

  @Parameters
  public static Collection<Object[]> getParameters()
  {
    return Arrays.asList(new Object[][] {
      { new GoodInterfaceImpl() },
      { new AnotherInterfaceImpl() }
    });
  }
}

このテストは2回実行されます。最初はGoodInterfaceImplを使用し、次にAnotherInterfaceImplクラスを使用します。しかし、問題は、ほとんどのテストケースに新しいオブジェクトが必要なことです。簡単な例:

@Test
public void isEmptyTest(){
   assertTrue(interface.isEmpty());
}

@Test
public void insertTest(){
   interface.insert(new Object());
   assertFalse(interface.isEmpty());
}

insertTestの後にisEmptyTestを実行すると、失敗します。

実装の新しいインスタンスで各テストケースを自動的に実行するオプションはありますか?

ところで:インターフェイスにclear()またはreset()メソッドを実装することは、生産的なコードでは必要ないため、実際にはオプションではありません。

4

4 に答える 4

8

テンプレートメソッドパターンを使用した別のアプローチは次のとおりです。

インターフェイス指向のテストは、基本クラスに入ります。

public abstract class MyInterfaceTest {

    private MyInterface myInterface;

    protected abstract MyInterface makeContractSubject();

    @Before
    public void setUp() {
        myInterface = makeContractSubject();
    }

    @Test
    public void isEmptyTest(){
        assertTrue(myInterface.isEmpty());
    }

    @Test
    public void insertTest(){
        myInterface.insert(new Object());
        assertFalse(myInterface.isEmpty());
    }
}

具体的なクラスごとに、具体的なテストクラスを定義します。

public class GoodInterfaceImplTest extends MyInterfaceTest {

    @Override
    protected MyInterface makeContractSubject() {
        // initialize new GoodInterfaceImpl
        // insert proper stubs
        return ...;
    }

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

@Parameterに対するわずかな利点は、テストが失敗したときに報告される具象テストクラスの名前を取得できるため、どの実装が失敗したかがすぐにわかることです。

ところで、このアプローチがまったく機能するためには、インターフェイスは、インターフェイスメソッドのみによるテストを可能にする方法で設計する必要があります。これは、状態ベースのテストを意味します。基本テストクラスのモックを検証することはできません。実装固有のテストでモックを検証する必要がある場合、これらのテストは具体的なテストクラスに入れる必要があります。

于 2013-02-23T22:42:24.127 に答える
6

ファクトリインターフェイスと実装を作成します。本番環境でそのようなものが必要ない場合は、テスト階層でのみ作成し、ファクトリgetParameters()のリストを返します。

次に、注釈付きメソッドでファクトリを呼び出して、@Beforeテストメソッドの実行ごとにテスト対象の実際のクラスの新しいインスタンスを取得できます。

于 2012-06-18T09:52:33.827 に答える
1

誰かがここに到達した場合に備えて(私が行ったように)、.netで同じインターフェイスの複数の実装をテストすることを探していると、ここのプロジェクトの1つで使用していたアプローチの1つを見ることができます。

以下は私たちが簡単にフォローしているものです

同じテストプロジェクトdllは、環境変数を設定することにより、vstest.consoleを使用して2回実行されます。テスト内で(アセンブリ初期化またはテスト初期化のいずれかで)、環境変数値に基づいて、適切な実装をIoCコンテナーに登録します。

于 2015-01-10T08:29:48.540 に答える
1

JUnit 5では、次のことができます。

@ParameterizedTest
@MethodSource("myInterfaceProvider")
void test(MyInterface myInterface) {}

static Stream<MyInterface> myInterfaceProvider() {
   return Stream.of(new ImplA(), new ImplB());
}

interface MyInterface {}

static class ImplA implements MyInterface {}

static class ImplB implements MyInterface {}
于 2017-11-05T10:23:09.650 に答える