如何使用Microsoft Shims来检测方法调用是否为DAMP
本文关键字:调用 是否 DAMP 方法 检测 何使用 Microsoft Shims | 更新日期: 2023-09-27 18:05:24
我在编写单元测试时遇到了以下问题。我想测试是否在SUT中调用了类的方法。我使用Microsoft Shims作为方法属于一个不实现任何接口的类(stub不能使用)。shim拦截方法调用,并在lambda中设置一个变量为true。该变量在lambda之外定义,但在相同的作用域中,因此可以捕获该变量。当我尝试将代码重构为DAMP(描述性和有意义的短语)时,问题就出现了,使用一个具有描述性名称的函数来封装shim创建,以及lambda。我被迫将变量传递给函数,然后让lambda捕获它,但这导致对变量的更改被限制在函数的范围内。我不能在参数上使用ref,因为我得到一个错误。我试图使用激进的内联自定义属性强制函数内联,但没有任何成功。由于c#不支持宏,我怎么能把它限制在一个函数中,而不是把它放在单元测试代码中,使它完全不可读?
这是在测试方法中设置shim的代码:
[TestMethod]
public void ATestMethod()
{
//Arrange the test...
bool myMethodHasBeenCalled = false;
using (ShimsContext.Create())
{
ShimMyClass.AllInstances.MyMethod =
(x) => {
myMethodHasBeenCalled = true;
};
//Act...
}
Assert.IsTrue(myMethodHasBeenCalled);
}
这是我想让我的代码…
private void DetectIfMyMethodHasBeenCalled(bool flag)
{
ShimMyClass.AllInstances.MyMethod =
(x) =>
{
flag = true;
};
}
[TestMethod]
public void ATestMethod()
{
//Arrange the test...
bool myMethodHasBeenCalled = false;
using (ShimsContext.Create())
{
DetectIfMyMethodHasBeenCalled(myMethodHasBeenCalled);
//Act...
}
Assert.IsTrue(myMethodHasBeenCalled);
}
不传递布尔参数,而是传递一个非常简单的类来包装布尔参数。
public class MethodTracer{
public bool WasCalled{ get; set; }
}
总是由ref传递,不会受到lambda的影响,甚至可能被认为比简单的布尔变量更具可读性。
添加积极的内联,ref
参数或out
参数不会使你的方法更潮湿。它只会把人搞糊涂:)。
[TestMethod]
public void ATestMethod()
{
//Arrange the test...
MethodTracer tracer = new methodTracer();
using (ShimsContext.Create())
{
ShimMyClass.AllInstances.MyMethod = _ => { tracer.WasCalled = true; };
//Act...
}
Assert.IsTrue(tracer.WasCalled);
}
或者让你的方法实际返回跟踪程序:
private MethodTracer DetectIfMyMethodHasBeenCalled()
{
MethodTracer tracer = new MethodTracer();
ShimMyClass.AllInstances.MyMethod = _ => { tracer.WasCalled = true; };
return tracer;
}
进行测试:
[TestMethod]
public void ATestMethod()
{
using (ShimsContext.Create())
{
var myMethodCallTracer = DetectIfMyMethodHasBeenCalled();
Assert.IsTrue(myMethodCallTracer.WasCalled);
}
}