web-dev-qa-db-ja.com

インターフェイスをどのようにユニットテストしますか?

たとえば、インターフェースIMyInterfaceがあり、3つのクラスがこのインターフェースをサポートしています。

class A : IMyInterface
{
}

class B : IMyInterface
{
}

class C : IMyInterface
{
}

最も簡単な方法では、ATest、BTest、CTestの3つのテストクラスを記述し、それらを別々にテストすることができます。ただし、これらは同じインターフェイスをサポートしているため、ほとんどのテストコードは同じであり、保守が困難です。 簡単で簡単な方法を使用して、さまざまなクラスでサポートされているインターフェイスをテストするにはどうすればよいですか?

以前にMSDNフォーラムで質問されました

24
Chetan

実装に関係なく、一般的なテストでインターフェイスをテストするには、抽象テストケースを使用してから、インターフェイスの実装ごとにテストケースの具体的なインスタンスを作成します。

抽象(基本)テストケースは実装中立テスト(つまり、インターフェイスコントラクトの検証)を実行し、具象テストはテストするオブジェクトのインスタンス化を処理し、実装固有のテストを実行します。

20
mdma

例としてNUnitを使用して、インターフェイスのさまざまな実装者に対して同じテストを実行する場合:

public interface IMyInterface {}
class A : IMyInterface { }
class B : IMyInterface { }
class C : IMyInterface { }

public abstract class BaseTest
{
    protected abstract IMyInterface CreateInstance();

    [Test]
    public void Test1()
    {
        IMyInterface instance = CreateInstance();
        //Do some testing on the instance...
    }

    //And some more tests.
}

[TestFixture]
public class ClassATests : BaseTest
{
    protected override IMyInterface CreateInstance()
    {
        return new A();
    }

    [Test]
    public void TestCaseJustForA()
    {
        IMyInterface instance = CreateInstance();   
        //Do some testing on the instance...
    }

}

[TestFixture]
public class ClassBTests : BaseTest
{
    protected override IMyInterface CreateInstance()
    {
        return new B();
    }
}

[TestFixture]
public class ClassCTests : BaseTest
{
    protected override IMyInterface CreateInstance()
    {
        return new C();
    }
}
41
Tim Lloyd

タイプIMyInterfaceのパラメーターを取り、実際のテストメソッドが異なる具象クラスを渡すメソッドを呼び出すだけのメソッドを作成できます。

3
Davy8

インターフェイスを直接テストすることはありませんが、特定の実装が拡張する必要があるコントラクトをテストする抽象クラスを作成することはできます。具象クラスのテストは、抽象クラスを拡張します

2
Kathy Van Stone

NUnitを使用している場合は、Grensesnittを使用できます。

public interface ICanAdd {
    int Add(int i, int j); //dont ask me why you want different adders
}

public class winefoo : ICanAdd {
    public int Add(int i, int j)
    {
        return i + j;
    }
}

interface winebar : ICanAdd {
    void FooBar() ; 
}

public class Adder1 : winebar {
    public int Add(int i, int j) {
        return i + j;
    } 
    public void FooBar() {}
}

public class Adder2 : ICanAdd {
    public int Add(int i, int j) {
        return (i + 12) + (j - 12 ); //yeeeeeaaaah
    } 
}

[InterfaceSpecification]
public class WithOtherPlugins : AppliesToAll<ICanAdd>
{ 
    [TestCase(1, 2, 3)] 
    [TestCase(-1, 2, 1)]
    [TestCase(0, 0, 0)]
    public void CanAddOrSomething(int x, int y, int r)
    {
        Assert.AreEqual(subject.Add(x, y), r);
    }

    [TestCase(1, 2, Result = 3)]
    [TestCase(-1, 2, Result = 1)]
    [TestCase(0, 0, Result = 0)]
    public int CannAddOrSomethingWithReturn(int x, int y) {
        return subject.Add(x, y);
    }
}
0
James