3

同様の質問がされていることは知っていますが、明確な解決策は見つかりませんでした。大規模なクラスからプライベート フィールドをモックしようとしています。プライベート フィールドは以前のメソッドでインスタンス化され、フィールドを参照する後者のメソッドを単体テストしようとしています。

したがって、クラスには以前のメソッドがあります。

public bool validateAll(ref DataEntry[] oEntries, string sMediaPlanId, ITemplateGenerator oTempGen)
{
  ...
  // private field that I am trying to mock
  this._sMediaPlanObjective = (MPWrapper.Instance).getMediaPlanObjective(sMediaPlanId);
  ...
}

そして、プライベート フィールドを参照するメソッドを単体テストしようとしています。

public bool validateFlightObjective(ref MPDataEntry oEntry)
{
  ...
  string entryFlightObjective = oEntry.getFlightObjective();
  string mediaPlanObjective = this._sMediaPlanObjective;

  if (entryFlightObjective != mediaPlanObjective)
  {
    return false;
  }
  ...

  return true;      
}

私は大規模なクラスを持っていて、これがテストしたいメソッドの 1 つにすぎないことを考えると、このプライベート フィールドを単にモックする方法はありますか? 基本的なものが欠けていますか、それとも他のアプローチを検討する必要がありますか?

4

3 に答える 3

5

プライベート、静的、または本質的にオーバーライドできないものをモックすることはできません(これは無料のモック ライブラリの制限として発生します)。

privateこのような状況 (メンバーテストする必要があると思われる場合) で通常行うことは、privateメンバーを別のクラスに抽出し、依存関係としてテスト済みのクラスに挿入することです。

あなたの場合、実際に_sMediaPlanObjectiveは次の行を作成するコードを抽出する必要があります。

this._sMediaPlanObjective =
    (MPWrapper.Instance).getMediaPlanObjective(sMediaPlanId);

メソッドを提供するオブジェクトはgetMediaPlanObjective、テスト対象のクラスに注入する必要があります。その場合は、単にそのオブジェクトをモックして、モックされたバージョンの を返すように指示できます_sMediaPlanObjective

于 2012-06-26T18:19:23.543 に答える
0

privateフィールドで何らかのテストを行う理由はありません。

publicオブジェクトを使用すると、オブジェクトAPIとしてメソッドを参照できます。オブジェクト自体は、実行する操作に応じて状態が変化する可能性がありますが、他のpublicメソッド/ DALへのアクセス(DB /レジストリ/ファイル/メモリにない他のリソース)に反映されます

したがって、あなたの場合、次のような単体テストを行うことができます。

期待どおりにプライベートフィールドを初期化するメソッドを呼び出し、-

  • 「状態になりたい」validateFlightObjectiveに従ってfalseを返す必要があることがわかっているパラメーターを使用して呼び出し、結果がfalseであることを確認します。_sMediaPlanObjective

  • 「状態になりたい」validateFlightObjectiveに従ってtrueを返す必要があることがわかっているパラメーターを使用して呼び出し、結果がtrueであることを確認します。_sMediaPlanObjective

このオブジェクトをテストするのが難しいことがわかった場合、それは「匂い」である可能性があります。おそらく、そこに複数の責任があり、リファクタリングを開始して、テストしやすい小さなクラスにクラスを分割する必要があります。

少し長いですが、お役に立てば幸いです。

于 2012-06-26T19:52:30.483 に答える
0

JustMock フレームワークを使用できます。例えば:

double value = 0;
var fakeFilterSetHelper = Mock.Create<FilterSetHelper>(Behavior.CallOriginal);
Mock.NonPublic.Arrange<double>(fakeFilterSetHelper, memberName: "GetPriceRangeFromSession").Returns(value);
于 2016-09-13T16:29:49.893 に答える