2013-08-03 37 views
6

私はインターフェイスの複数の実装をテストするために使用される一連のベーステストを持っています。私がこれをモードにしたのは、[Ignore]属性を持つベースのテキストフィクスチャを作成することでした。テストフィクスチャ継承と無視されたベーステストフィクスチャ

[TestFixture] 
[Ignore] 
public class BaseTests 
{ 
    // Use your imagination for the actual name 
    public virtual ITestableThing GetConcrete() 
    { 
     return null; 
    } 

    // All of my unit tests here 
} 

そして私は、各インターフェイスの実装のためのサブクラスを書く:

public class ConcreteThingTests : BaseTests 
{ 
    public override ITestableThing GetConcrete() 
    { 
     return new ConcreteThing(); 
    } 
} 

私は1つの場所ですべての実装のためのテスト、およびサブクラスのすべてがちょうど指定する必要があり、これは、うまく機能実装。

問題は、基本クラスに[Ignore]属性を設定するか、NUnitがテストを実行しようとして失敗することです。

私のテスト結果は、無視されたテストセットで常に詰まっていますが、大したことではありませんが、テストを無視しなければならないことを避けるためのより良いパターンがあると思いました。

私はテストフィクスチャーの継承を間違って実装していますか?

答えて

4

通常、テスト属性は基本クラスではなく、具体的なテストクラスに設定します。

複数のクラスに対して同じ機能をテストするように見えるので、テスト階層全体をスキップして、テストする具体的なクラスをそのテストベースクラスに注入できます。

NUnitを使用するには、クラスファクトリメソッドをパラメータとしてTestCaseSource属性を使用できます。その例としては、ここで見つけることができます:あなたの特定のケースのためのいくつかのコードを構成するHow to pass dynamic objects into an NUnit TestCase function?

、それは同様に、以下に示すことができます:

/// <summary> 
/// Earlier known as your BaseTests class 
/// </summary> 
[TestFixture] 
public class TestOfConcreteImplementationsOfInterface 
{ 
    [TestCaseSource("CreateConcretes")] 
    [Test] 
    public void VerifyImplementations(IWhatever thing) 
    { 
     int input = 42; 
     int result = thing.DoSomething(input); 
     Assert.That(result, Is.EqualTo(input)); 
    } 

    /// <summary> 
    /// Factory method for the concrete classes. If you want this in a seperate class, you can do that too using the 
    /// ctor public TestCaseSourceAttribute(Type sourceType, string sourceName); 
    /// </summary> 
    public IEnumerable<IWhatever> CreateConcretes 
    { 
     get 
     { 
      yield return new A(); 
      yield return new B(); 
     } 
    } 
} 

public interface IWhatever 
{ 
    int DoSomething(int x); 
} 

public class A : IWhatever 
{ 
    public int DoSomething(int x) 
    { 
     return x; 
    } 
} 

public class B : IWhatever 
{ 

    public int DoSomething(int x) 
    { 
     return x; 
    } 
} 
+1

私がこれを持っている問題は、テストクラスに基本クラスを密接に結合することです。新しい実装を作成して仕様に照らしてテストしたい人は、属性を追加したりメソッドを変更するために基本クラスを変更する必要はありません。 –

13

NUnitのテストランナーは、それがある場合は、基本クラスを無視するように見えます指定された抽象度:

+0

Spot on。上院議員。 –

+0

ブーム。完璧。私は抽象的なテストフィクスチャベースを持っていましたが、そこから継承された第2レベルのフィクスチャベースを作成すると、NUnitはそれに不満を持ち始めました。サブクラスにアブストラクトが追加されました。リー=ザ・マン(tm)。 –

+1

名前空間外の抽象クラスだと思います。私が抽象として同じプロジェクトに私をコピーしたとき、それは働いたが、彼らは異なるプロジェクトにいたときではなかった。 Nunitのバージョンも同じでなければならなかった –

関連する問題