【问题标题】:Moq can Mock HubConnection but RhinoMocks can't?Moq 可以模拟 HubConnection 但 RhinoMocks 不能?
【发布时间】:2014-07-16 15:19:41
【问题描述】:

我正在查看 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 : Invalid call, the last call has been used or no call has been made (make sure that you are calling a virtual (C#) / Overridable (VB) method).

与 Moq 等较新的库相比,这只是 RhinoMocks 的一个缺点吗?

【问题讨论】:

  • 啊,我认为问题在于 Send 确实是可以覆盖的。而CreateHubProxy 不是。我只是在比较苹果和橙子。

标签: c# unit-testing signalr moq rhino-mocks


【解决方案1】:

我的建议是使用代码中的非具体类型并使用 Ioc 注入具体类型。然而,signalr dot net 客户端缺少与服务器不同的 DependencyResolver。我推出了自己的解决方案,您可以在此处查看代码(但在您的情况下,您可以使用任何 Ioc,如 Ninject、autofac 等)

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

所有示例均取自我的 dot net 客户端,用于此库 https://github.com/AndersMalmgren/SignalR.EventAggregatorProxy

【讨论】:

  • 这是一个很好的评论,它触及了我的问题的根源:摆脱对 HubConnection 的直接依赖。但是,周围有一个 HubConnection 很有用,因为您可以检查您的连接状态并在第一次未能正确初始化时重试连接。以您的为例,对此有什么想法吗?
  • 好吧,如果 IHubProxy 没有提供正确的成员,那么您必须创建自己的接口,用正确的成员抽象集线器代理
  • 是的,我最终为班级创建了自己的“包装器”:gist.github.com/killnine/05c47128735201c32ddc。可以稍后打包。我希望 SignalR 在默认情况下更优雅地处理这个问题。
猜你喜欢
  • 1970-01-01
  • 2021-05-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多