2016-04-04 12 views
1

は、私はメソッドを持っている、のは言わせてA、B、C、Dのユニットテストにおける内部メソッドの呼び出しをスキップ

public bool A (int foo) 
{ 
    bool result = false; 
    if (foo > 0) 
     result = B(); 
    else result = C(); 
    D(foo); 
    return result; 
} 

私はBまたはCを呼び出して、Aのためのユニットテストを書きたい、しかししたいですDコールをスキップします(外部サービスを使用する方法なので)。いくつかの属性を使用してDコールをスキップすることは可能ですか?またはDを偽装して、それを偽のサービスに置き換えてください。

+0

'A'メソッドを入力すると' D'を呼び出すことはできません。 –

+0

はい、あなたはMock * D *をしなければなりません。 – bit

+0

どちらの場合でも、 'D'呼び出しをスキップしたいのは問題そのものです。ユニットを変更したくない場合は、それは本物のテストではありません。あなたのテストでは、コードの単位をブラックボックスのビットとして扱うべきです。 "私はそれにこの入力を与える、私はこの出力を期待しています。 –

答えて

1

メソッドA()を持つクラスを、メソッドD()で使用される外部サービスに依存させる必要があります。 DIパターンのいずれかを使ってこれを行うことができますが、コンストラクタインジェクションはおそらく最善の出発点です。

この状況になると、D()の外部サービスが偽装され、クラスに注入されることになります。テストは現在、偽の動作によって制御されています。その後

class Thing 
{ 
    private IExternalService _externalService; 

    public Thing(IExternalService externalService) 
    { 
     _externalService = externalService; 
    } 

    public void A() { ... } 

    public void D(string foo) 
    { 
     _externalService.DoSomeStuff(); 
    } 
} 

::のような

何か

[Fact] 
public void TestThisOut() 
{ 
    var fakeExternalService = new MockFramework.CreateMock(); 
    fakeExternalService 
     .ShouldDoSomethingWhen(s => s.DoSomeStuff()) 
     .IsCalled(); 

    var testThing = new Thing(fakeExternalService); 

    testThing.A(); 

    Assert.That(testThing, Did.Some.Thing()); 
} 
1

これは、コードを単体テストできるように設計することの重要性を強調しています。依存関係注入はこの点で非常に有用です。単体テスト時に依存関係を模擬することができます。たとえば、通信インタフェースを介してアクセスできる通信レイヤがあるとします。あなたのクラスは、そのコンストラクタにICommunicationsオブジェクトへの参照を取る:

public class TestableClass 
{ 
    private ICommunications _comms; 
    public TestableClass(ICommunications comms) 
    { 
     _comms = comms; 
    } 

    public bool FunctionToTest() 
    { 
     //do something testable 

     _comms.SomeFunction();//mocked object in unit tests 

     //do something else testable 
    } 
} 

は、それからちょうど途切れのモックバージョンを作成し、テスト中にそれを渡します。モックされたクラスにコードを追加して、特定のテスト条件をエミュレートすることもできます。たとえば、無効なデータを受け取っている通信レイヤーです。

0

あなたは方法D.を模擬する必要があるが、私は見てみましょう、Typemockアイソレータを使用して、例を書いた:

class Methods 
{ 
    public bool A(int foo) 
    { 
     bool result = false; 
     if (foo > 0) 
      result = B(); 
     else 
      result = C(); 
     D(foo); 
     return result; 
    } 

    public void D(int foo) {throw new NotImplementedException();} 

    public bool C() { return false;} 

    public bool B() { return true;} 
} 

そして、テスト:

[TestMethod, Isolated] 
public void TestIgnoreD() 
{ 
    //Arrange 
    Methods methods = new Methods(); 
    Isolate.WhenCalled(() => methods.D(0)).IgnoreCall(); 

    //Act 
    bool result = methods.A(1); 

    //Assert 
    Assert.IsTrue(result); 
} 

あなたのコードで何が起こっているのか分からないからといって、それらをすべて1つのクラスに入れます。とにかく、ほぼすべての場所からほぼすべてを模擬することができるので、アイソレータはかなり柔軟です。

関連する問題