惩戒私有字段(Mocking a private field)

2019-09-18 13:15发布

我知道类似的问题已经被问,但我还没有找到一个明确的解决方案。 我试图从一大类嘲笑的私人领域。 私人领域被实例化在一些早期的方法,我试图单元测试它引用领域的后一种方法。

所以,我在我的类较早方法:

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

既然我有一大类,这只是其中的一个方法我想测试,是有可能的办法只有嘲笑这个私人领域? 我失去了一些基本的东西还是应该考虑一些其他的方法呢?

Answer 1:

你不能嘲笑任何私人的,静态的,或基本-非重写(这是作为一个免费的嘲弄库限制 )。

你通常在这种情况下什么(当它出现的是private成员需要进行测试),在提取你的private成员到一个单独的类,并注入它来测试类的依赖。

在你的情况,你确实需要提取创建代码_sMediaPlanObjective ,这是这一行:

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

提供对象getMediaPlanObjective方法应注射到你的测试类。 如果你这样做,你可以简单地嘲笑那个对象,并告诉它返回的嘲笑版本_sMediaPlanObjective



Answer 2:

没有理由让任何形式的对测试private领域。

使用一个对象,你可以参考public的方法为对象的API。 对象本身可以有它的变化状态,根据你就可以执行的操作-但它会在其他反映public方法/访问DAL(DB /注册表/文件/任何其他资源,是不是在内存中)

所以你的情况,你可以有一个单元测试这样的:

调用初始化,你期望它和私营领域的方法 -

  • 呼叫validateFlightObjective ,你知道有根据返回false参数_sMediaPlanObjective “想成为国家”,并验证结果是假的。

  • 呼叫validateFlightObjective ,你知道有根据返回true参数_sMediaPlanObjective “想成为国家”,并验证结果是真实的。

如果你看到它是很难测试这个对象,那么这可能是一个“嗅觉” - 也许你有一个以上的责任那里,你应该开始重构和分割类小班授课,这将是更容易测试

这有点长,但我希望这是有益的



Answer 3:

您可以使用JustMock框架。 例如:

double value = 0;
var fakeFilterSetHelper = Mock.Create<FilterSetHelper>(Behavior.CallOriginal);
Mock.NonPublic.Arrange<double>(fakeFilterSetHelper, memberName: "GetPriceRangeFromSession").Returns(value);


文章来源: Mocking a private field