Moq可以模拟HubConnection,但是RhinoMocks不能吗?

我正在查看SignalR的unit tests,并注意到其中一项测试使用Moq创建模拟HubConnection:

[Fact]
public void HubCallbackClearedOnFailedInvocation()
{
    var connection = new Mock<HubConnection>("http://foo");
    var tcs = new TaskCompletionSource<object>();

    tcs.TrySetCanceled();

    connection.Setup(c => c.Send(It.IsAny<string>())).Returns(tcs.Task);

    var hubProxy = new HubProxy(connection.Object, "foo");

    var aggEx = Assert.Throws<AggregateException>(() => { hubProxy.Invoke("foo", "arg1").Wait(); });
    var ex = aggEx.Unwrap();

    Assert.IsType(typeof(TaskCanceledException), ex);

    Assert.Equal(connection.Object._callbacks.Count, 0);
}

但是,当我尝试使用稍微不同的模拟框架RhinoMocks进行相同操作时,它会抱怨该方法不是虚拟的:

[Test]
public void ShouldCreateBrokerWithHubConnection()
{
    //Arrange
    var url = "http://localhost6790";
    var hubProxy = MockRepository.GenerateMock<IHubProxy>();
    var hubConnection = MockRepository.GenerateMock<HubConnection>(url);
    hubConnection.(c => c.CreateHubProxy("ArtemisClientHub")).Return(hubProxy);

    ... (more code)
 }

System.InvalidOperationException:无效的调用,已使用最后一个调用,或者未进行任何调用(确保您正在调用虚拟(C#)/可重写(VB)方法).

与像Moq这样的较新库相比,这仅仅是RhinoMocks的缺点吗?

解决方法:

我的技巧是使用代码中的none具体类型,并使用Ioc注入具体类型.但是,与服务器不同,信号点网络客户端缺少DependencyResolver.我自己动手解决了这个问题,您可以在此处查看代码(但您可以使用Ninject,autofac等任何Ioc)

https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/blob/master/SignalR.EventAggregatorProxy.Client.DotNet/Bootstrap/DependencyResolver.cs

集线器连接和代理有点抽象,因为您依赖于创建代理的具体类型.我通过将集线器代理的创建抽象到工厂接口来解决此问题,该接口返回可以轻松模拟的IHubProxy.

看这里
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy/blob/master/SignalR.EventAggregatorProxy.Client.DotNet/Bootstrap/Factories/HubProxyFactory.cs

所有示例均取自该库的点网客户端
https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy

上一篇:Android动态权限申请


下一篇:c# – SignalR未触发OnDisconnected