2016-05-10 4 views
-1

C# Mock a Class With an Internal Property Setter部品番号とモック方法とmoq.Objectを利用できるようにするには

ここで私が持っているものの要約。

私はInterfaceを次ています

public interface IPosition 
{ 
    // Some properties here which must be accessed in CalcValueChangeAtDate method. 
    int Size { get; } 
    ... 

    double CalcValueChangeAtDate(DateTime fromDate, DateTime toDate); 
} 

そして、私はこのようなクラスRealPositionにインターフェイスを実装:

:私は IPositionインタフェースを使用して別のクラスを作成しさらに

public class RealPosition : IPosition 
{ 
    /* IPosition implementation */ 
    public double CalcValueChangeAtDate(DateTime fromDate, DateTime toDate) 
    { 
     return CalcValueChangeAtDate(this, fromDate, toDate); 
    } 

    /* I created this static method with the idea to use the for mocked objects. 
    * This way I would need to implement the logic only once and use it with real 
    * and mocked objects*/ 
    public static double CalcValueChangeAtDate(IPosition pos, DateTime fromDate, DateTime toDate) 
    { 
     // Logic here must access properties of IPosition 
    } 
} 

私のテストセットアップは次のようになります。

[Test] 
public void RecalcOriginalEquityCurve() 
{ 
    // Here I get a list of mocked IPositions 
    List<IPosition> Positions = ImporterTools.GetPositions(FilePath, FullPositionsCsv); 

    // Execute Test 
    DataSeries equityCurve  = EquityCurveBuilder.BuildEquityCurve(Positions); 

    // Evaluate test results 
    ... 
} 

public class ImporterTools 
{ 
    public static List<IPosition> GetPositions(string path, string fileName) 
    { 
     // Import raw data and create a mocked IPosition 
     Mock<IPosition> tmpPosMoq = new Mock<IPosition>(); 
     tmpPosMoq.Setup(v => v.CalcValueChangeAtDate(It.IsAny<DateTime>(), It.IsAny<DateTime>())). 
                      Returns(???); 

     // Create a List and return it 
    } 
} 

問題は、ユニットテストではすべて私が嘲笑している位置です。しかし、CalcEquityCurve()メソッドは、IPostionCalcValueChangeAtDate()を呼び出します。 CalcEquityCurve()を正しくテストするには、CalcValueChangeAtDate()が有効な値を返す必要があります。戻り値は、メソッドの引数に依存します。従って、模擬オブジェクトがstaticメソッドRealPosition.CalcValueChangeAtDate()を呼び出すという考え方。

今、私は???で立ち往生しています。

tmpPosMoq.Object.CalcValueChangeAtDate(fromDate, toDate); 

はそれが可能ですべてです:私は単に私が呼ぶときRealPositionクラスからの私staticメソッドが呼び出されるように、そこに書き込むためにどのような任意のアイデアを持っていませんか?

ありがとうございました!

tmpPosMoq.Setup(v => v.CalcValueChangeAtDate(It.IsAny<DateTime>(), It.IsAny<DateTime>())). 
       Returns((DateTime dtfrom, DateTime dtto) => 
       { 
        return RealPosition.CalcValueChangeAtDate(tmpPosMoq.Object, dtfrom, dtto); 
       }); 

をしかし、これは完全に無意味です: コンスタンチン

+0

あなたのコメントで 'CalcValueChangeAtDate'を判断すると、あなたはモックのポイントを見逃していると思います。モックを可能な限り単純なものに戻すことができるようにしてください。これは、使用しているものが何であっても知ることができます。この場合は、「ダブル」のような魔法の数字になります。 '1.2345'のようなものを返し、テスト中のシステムがその値を取得していることを確認します。 –

+0

実際の実装を呼び出す場合は、何かを模倣しないでください。あなたの目標がモックのためにどうなっているかは非常に不明です。 – Crowcoder

+0

@Crowcoder: 入力いただきありがとうございます。私は説明を変更し、今私の目標が明確になることを願っています。 – Konstantin

答えて

1

は、あなたの質問に答えるために、私はこれがあなたが求めているものだと思います。実際の実装を呼び出す複雑で畳み込まれた方法です。まるで模擬しなかった場合とまったく同じです。単位テストは、ビジネスロジックをテストするためのテストです。 Mockingは、実際にユニットテストできないもの(データベース呼び出し、Webサービス呼び出しなど)から通常得られる擬似で現実的な値を提供するためのものです。

// Logic here must access properties of IPosition 

...は嘲笑の候補です。しかし、あなたのコンストラクタに依存関係がないので、私は推測もできません。

+0

それは私が必要とするものです。私は単に引数として 'v'を使うことができないことを知りました。しかし、私は次の3つのエラーメッセージを受け取ります: 1)ラムダ式がデリゲート型ではないので、double型に変換することはできません 2)デリゲート 'System.Func 'は2つの引数を取らない 3) 'v'という名前は現在のコンテキストに存在しません 私はそれを修正するために何が必要なのでしょうか? – Konstantin

+0

PS: 申し訳ありませんが、私は自分の考えを明確にすることができませんでした。私は 'EquityCurveBuilder.CalcEquityCurve()'をテストしたいだけです。特定のfromDate/toDateの組み合わせに対して特定の値を返さなければならないことを理解しています。しかし、それを行うことは非常に非現実的になるほど多くあります。したがって、私は、すでにテストされたメソッドを呼び出す方法でモックをセットアップして、必要な値を単純に計算する必要があります。 – Konstantin

+0

私はその文脈で 'v'を使うことはできないと思います。その代わりに 'tmpPosMoq.Object'を試しましたか? – Crowcoder

関連する問題