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;      
}

鉴于我有一个大班,这只是我想测试的一种方法,有没有可能的方法来模拟这个私有字段?我错过了一些基本的东西还是应该考虑其他方法?

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 的访问中(数据库/注册表/文件/任何其他不在内存中的资源)

因此,在您的情况下,您可以进行这样的单元测试:

按照您的期望调用初始化私有字段的方法,然后 -

  • validateFlightObjective使用您知道必须根据“想要成为状态”返回 false 的参数调用_sMediaPlanObjective,并验证结果是否为 false。

  • validateFlightObjective使用您知道必须根据“想要成为状态”返回 true 的参数调用_sMediaPlanObjective,并验证结果是否为 true。

如果你发现很难测试这个对象,那么这可能是一种“气味”——也许你在那里有不止一个责任,你应该开始重构并将类拆分为更容易测试的更小的类

它有点长,但我希望它有帮助

于 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 回答