4

在为 BCL(或任何库)中的类型成员创建 shim 时。我们经常面临这样一种情况,我们想要调用我们已经覆盖的原始方法(无论是在 shim 委托内部还是外部)。例如:

System.Fakes.ShimDateTime.NowGet = () => DateTime.Now.AddDays(-1);

在上面的代码中,当调用 DateTime.Now 时,我们要做的就是返回比实际日期少一天的时间。也许这看起来像是一个人为的例子,所以其他(更)现实的场景是

  1. 能够捕获和验证传递给特定方法的参数值。
  2. 能够计算被测代码访问特定方法/属性的次数。

我在实际应用程序中遇到了最后一种情况,但在 SO 上找不到 Fakes 的答案。但是,在深入研究 Fakes 文档后,我找到了答案,因此将其与社区的问题一起发布。

4

1 回答 1

8

假货对此有内置支持;实际上有两种方法可以实现这一点。

1) 使用 ShimsContext.ExecuteWithoutShims() 作为您不需要 shim 行为的代码的包装器:

System.Fakes.ShimDateTime.NowGet = () => 
{
return ShimsContext.ExecuteWithoutShims(() => DateTime.Now.AddDays(-1));
};

2)另一种方法是将shim设置为null,调用原始方法并恢复shim。

FakesDelegates.Func<DateTime> shim = null;
shim = () => 
{
System.Fakes.ShimDateTime.NowGet = null;
var value = ShimsContext.ExecuteWithoutShims(() => DateTime.Now.AddDays(-1));
System.Fakes.ShimDateTime.NowGet = shim;
return value;
};
System.Fakes.ShimDateTime.NowGet = shim;

编辑:显然第一种方法更简洁易读。所以我更喜欢它而不是显式声明 shim 变量并删除/恢复 shim。

于 2013-12-09T19:48:16.207 回答