2016-08-18 5 views
2

変更できない外部クラスがあるC#プロジェクトのユニットテストを作成しようとしています。それはインターフェイスから実装されておらず、メソッドは仮想ではありません。バーチャルとして宣言されていない外部クラスのメソッドをモックする方法

このクラスのメソッドとそのメソッドが設定するクラスプロパティから戻ってくる結果を疑似したいと思います。

だから、私はテストしていたコードは次のようである外部クラスに

public class RatioThreadProcessor { 
    public SqlString dbName;   
    public List<Instrument> units; 
    public Results Results; 
    etc 
    public void Process() { 

     // Does stuff 
     // I want this to be called for real but not in my test case 
    } 

を持っている:

public class MockRatioThreadProcessor : RatioThreadProcessor 
    { 
     public new void Process() 
     { 
      // mock Logic 
      // I want this to be called in my test case 
     } 
    }  

    private Mock<RatioThreadProcessor> mockRatioThreadProcessor; 
    public void SetUp() 
    { 
     mockRatioThreadProcessor = new Mock<MockRatioThreadProcessor(); 
     mockRatioThreadProcessor.SetUp(r => r.Process()); 
    } 
    public void TestMethod() 
    { 
     var fundInfoRatioService = new FundInfoRatioService(null);   
     fundInfoRatioService.ratioThreadProcessor = mockRatioThreadProcessor.Object; 
     fundInfoRatioService.MethodUnderTest(); 
     // assert results 
    } 
:私のようなものをやってみたかった

public class FundInfoRatioService 
{ 
    public RatioThreadProcessor ratioThreadProcessor; 

    public FundInfoRatioService() 
    { 
     ratioThreadProcessor = new RatioThreadProcessor(); 
    } 

    public MethodUnderTest() 
    { 
     ratioThreadProcesor.dbName = "as"; 
     ratioThreadProcessor.Process(); 
     var results = ratioThreadProcessor.Results; 
     // important logic I want to test 
    } 

し、それをテストします

私が持っている問題は、基本のProcessメソッドが常に呼び出され、呼び出されたかった模擬のメソッドではないということです。

私はそれが継承されたものに初期化されているとしても、C#は常にそれが宣言されている変数のメソッドを呼び出すためだと思います。

私はこのテストを行い、外部クラスのProcessメソッドをモックできますか?

ありがとう

Tim。あなたが取ることができ

+2

仮想でない限り、Moqでモックすることはできません。元のコードを呼び出すアダプタを作成する必要がありますが、それをvirutalメソッドで呼び出してからモックします。 – Crowcoder

+0

私はまた、嘲笑自体に疑問を呈します。この外部メソッド内のロジックをテストしていますか?あなたがその場合、なぜ偽をするのですか?そうでない場合は、セットアップを使用して返品またはカウンターを呼び出します。 (mockRatioThreadProcessor.SetUp(r => r.Process())。コールバック(()=> i ++); ) – Alok

答えて

4

一つのアプローチは、RatioThreadProcessor周りのラッパークラスを作成することです:

class RatioThreadProcessorWrapper : IThreadProcessor 
{ 
    private readonly RatioThreadProcessor _ratioThreadProcessor; 

    public RatioThreadProcessorWrapper() 
    { 
     _ratioThreadProcessor = new RatioThreadProcessor(); 
    } 

    public Process() => ratioThreadProcessor.Process(); 
    ... 
} 

FundInfoRatioServiceに(IThreadProcessorへの参照を経由して)それを注入します。

ただし、MethodUnderTestの方法を検討する価値はあります。この方法:

  1. RatioThreadProcessorのインスタンスを変更し、
  2. コールProcess
  3. は結果に何かを、いくつかの結果を取得します。

あなたは4つのことを行う1つの方法があります。最初の3つをメソッドの外に移動し、(4)の1つの責任しか持たない場合は、テスト結果オブジェクトを渡してその方法をテストし、RatioThreadProcessorから切り離すことができます。

+1

素晴らしい解決策です。どうもありがとう。 – TimBunting

関連する問題