2017-02-21 23 views
1

対応するユニットテストと共に配列ベースのスタックデータ構造を実装しました。このスタックは私のIStackインターフェイスを実装しています。だから、現時点では、私のUTクラスはそのようなことになります。今ユニットテストにおける依存性注入

[TestClass] 
public class Stack_ArrayBased_Tests 
{  
    //check against empty collection 
    [TestMethod] 
    public void IsEmpty_NoElements() 
    { 
     var myStack = new Stack_ArrayBased_Example1(10); 

     var exp = true; 
     var act = myStack.IsEmpty(); 
     Assert.AreEqual(exp, act); 
    } 

を、私は、スタックベースのリンクリストを実装しようとしています。このスタックは、同じIStackインターフェイスから継承されます。

私はユニットテストリンクされたリストのスタックもしたいと思います。どちらも同じインターフェースから継承しているので、不必要なコードの重複を防ぐために、すでに実装されているUnit Testを利用できるはずです。

ユニットテストクラスを2つ(ユニットベースのスタック用、リンクベースのスタック用)に作成する最も良い方法は、同じユニットテストメソッドを使用しますか?私はDependency Injectionが答えになると思っていますが、私はそれについてどうやって行くのでしょうか?

+0

としてジェネリックStackTestで使用することができます両方のシナリオを独自のクラスにまとめて、異なるユースケースで使用することができます。したがって、すでにテストケース1の実装が*リファクタリングしている場合は、その動作を独自のクラスにリファクタリングし、両方のテストでインスタンスを使用します。 – HimBromBeere

答えて

2

別の方法でロジックを分離することができます。

[TestMethod] 
public void IsEmpty_NoElements_ArrayBased() 
{ 
    var myStack = new Stack_ArrayBased_Example1(10); 
    IsEmpty_NoElements(myStack) 
} 

[TestMethod] 
public void IsEmpty_NoElements_LinkedListBased() 
{ 
    var myStack = new Stack_LinkedListBased_Example1(10); 
    IsEmpty_NoElements(myStack) 
} 

public void IsEmpty_NoElements(IStack myStack) 
{ 
    var exp = true; 
    var act = myStack.IsEmpty(); 
    Assert.AreEqual(exp, act); 
} 
4

依存性注入は、テストに関しては決して答えではありません。

抽象度をテストしているわけではありません。具体的な実装をテストすることは不可能です。ただし、抽象クラス、インタフェース、抽象クラスをモックできます。

コードを再利用する唯一の目的でいくつかのクラスを作成し、そのクラスをテストメソッドから呼び出すことができます。これは大丈夫で完全に実行可能です。

具体的な実装ごとに2つのテストクラスが必要であり、作成した新しいクラスを両方とも呼び出す必要があります。これにより、コードの重複が回避されます。

0

たちは

public interface IStack 
{ 
    bool IsEmpty { get; } 
} 

public class StackImpl1 : IStack 
{ 
    public StackImpl1(int size) 
    { 
    IsEmpty = true; 
    } 

    public bool IsEmpty { get; } 
} 

public class StackImpl2 : IStack 
{ 

    public StackImpl2(int size) 
    { 
    IsEmpty = true; 
    } 

    public bool IsEmpty { get; } 
} 

を以下していると言うそして、私たちはOPからIsEmpty_OnCreation()テストを実施したいです。私たちはできます共通のテストを行い、複数のinvoker(テストする各実装の1つ)を追加します。問題は拡大縮小です。

我々は

1を追加する必要がテストするための機能のそれぞれの新しい部分のための

)テスト実装
2)試験対象の各実装のための呼び出し。

新しい導入については、既存のテストごとに呼び出し元を追加する必要があります。

テストが各派生固定具に生成されている私たち

public abstract class StackTest 
{ 
    protected abstract IStack Create(int size); 

    [TestMethod] 
    public void IsEmpty_NoElements() 
    { 
    var myStack = Create(10); 

    var exp = true; 
    var act = myStack.IsEmpty; 
    Assert.AreEqual(exp, act); 

    } 
} 

[TestClass] 
public class StackImp1Fixture : StackTest 
{ 
    protected override IStack Create(int size) 
    { 
    return new StackImpl1(size); 
    } 
} 

[TestClass] 
public class StackImp2Fixture : StackTest 
{ 
    protected override IStack Create(int size) 
    { 
    return new StackImpl2(size); 
    } 
} 

のためにほとんどの作業を行うために、継承を使用することが可能です。

新しいテストを追加したい場合は、StackTestクラスに追加し、それが自動的に各派生フィクスチャに含まれます。

IStackの3番目の実装を追加する場合は、StackTestから派生した新しいテストフィクスチャを追加し、createメソッドをオーバーライドするだけです。

注:テスト対象のクラスは、デフォルトコンストラクタを持っている場合は、あなたが属しているコードをリファクタリングする必要があり、他のコードと同じように
、同じ形状をベース

public class GenStackTest<TStack> where TStack : IStack, new() 
{ 

    [TestMethod] 
    public void IsEmpty_NoElements() 
    { 
    var myStack = new TStack(); 

    var exp = true; 
    var act = myStack.IsEmpty; 
    Assert.AreEqual(exp, act); 

    } 
} 

[TestClass] 
public class GenStack1Fixture : GenStackTest<StackImpl1> 
{ 
} 

[TestClass] 
public class GenStack2Fixture : GenStackTest<StackImpl2> 
{ 
}