[英]Mocking Action<T> with NSubstitute
Web服务的代理需要进行单元测试,而不会(显然)击中Web服务。
这是我想绝育的方法-
public void Invoke(Action<T> action)
{
Task.Run(async ()=> { await _invoker.Invoke(this, action); }).Wait();
}
有什么方法可以使用NSubstitute模拟Action参数吗? 我一直在努力使用
_proxy.When(x => x.Invoke($args_go_here)).Do(x => _counter++);
但是我在编写Args表达式时遇到了麻烦。 如果我可以使用Action签名简单地创建一个模拟并将其传递,生活将变得更加简单和可读。
随着David的评论(请参阅问题评论),我在这里发布实际上解决了我的问题的内容。
问题是测试调用WCF服务的代码是否正在实际运行,发送正确的东西等。我非常强烈地建议任何沿着这条路线走的人都以TDD风格这样做,因为对其他人的工作代码进行单元测试改型不是愉快的经历。
在这种情况下,代理不会自动生成,而是从暴露了上面引用的Invoke(Action action)方法的单个ProxyBase类继承而来。
public void Invoke(Action<T> action)
{
Task.Run(async ()=> { await _invoker.Invoke(this, action); }).Wait();
}
我的第一个想法是模拟Action(最终确实这样做了),但这确实产生了Service Not Found错误。
最终,我得到了(特定的)Proxy Invoker类的NSubstitute Automock,它是通过将依赖项实际上传递给构造函数而创建的,如下所示:
var myProxyMock = Substitute.For<MyProxy>(dependency1, dependency2);
然后将基本invoke方法更改为Virtual,以便替代方法可以覆盖它,例如,
public virtual void Invoke(Action<T> action)
{
Task.Run(async ()=> { await _invoker.Invoke(this, action); }).Wait();
}
现在,通过替换Action,我实际上可以有效地测试周围的代码。
var actionSubstitute = Substitute.For<Action<MyService>>();
并应用相关的返回值,natch。
所以最终,我们有-
myProxyMock.When(x => x.Invoke(Arg.Any<Action<MyService>>).Do(x => _counter++);
问题解决了。 非常感谢,大卫。
如果您只想做一个间谍而不做任何外部跟踪变量(Rich Bryant的最佳答案是_counter
),则可以在替代项上使用ReceivedCalls()
。 下面的示例使用System.Linq
:
var myAction = Substitute.For<Action<string>>();
myAction.Invoke("abc");
// assert the Action<string> was called once
Assert.Equal(1, myAction.ReceivedCalls().Count());
// assert that the first parameter on the first call was "abc"
Assert.Equal("abc", myAction.ReceivedCalls().First().GetArguments().First());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.