【问题标题】:Mock SignalR hub for testing dependent class用于测试依赖类的模拟 SignalR 集线器
【发布时间】:2019-05-22 10:02:40
【问题描述】:

我正在尝试实例化一个处理一堆功能的类,并使用依赖注入构建。我模拟了两个参数,第三个是内存数据库上下文。现在断言时,它会在mockClientProxyParticipants.Verify() 行上引发错误:

System.NotSupportedException : 扩展方法验证无效:proxy => proxy.SendAsync(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<CancellationToken>())

几乎不可能不调用该函数,并且以Times.Never() 作为参数调用Verify() 不会改变任何内容。

我尝试使用mockClientProxyResults.Verify() 等普通字符串设置Verify() 的Linq 参数,我尝试使用It.Is<string>(s => s == "some string") 并尝试It.IsAny<string>()

老实说,我现在不明白出了什么问题。这是我的测试代码,如果您想查看更多内容,请告诉我:

var mockHub = new Mock<IHubContext<VoteHub>>();
var mockClients = new Mock<IHubClients>();
var mockClientProxyParticipants = new Mock<IClientProxy>();
var mockClientProxyResults = new Mock<IClientProxy>();

mockClients.Setup(clients => clients.Group("Participants")).Returns(mockClientProxyParticipants.Object);
mockClients.Setup(clients => clients.Group("Results")).Returns(mockClientProxyResults.Object);
mockHub.Setup(hub => hub.Clients).Returns(mockClients.Object);

var activeQuestionManagerMock = new Mock<IActiveQuestionManager>();
activeQuestionManagerMock.Setup(x => x.GetActiveQuestion())
    .Returns(new ActiveQuestionModel(options));

QuestionHandler qm = new QuestionHandler(new VoteDbContext(options), mockHub.Object, activeQuestionManagerMock.Object);

//Act
qm.Ask(question);

//Assert
mockClientProxyParticipants.Verify(proxy => proxy.SendAsync(It.IsAny<string>(/*s => s == "AskQuestion"*/), It.IsAny<string>(/*s => s == qwaJSON*/), It.IsAny<CancellationToken>()), Times.Once());
mockClientProxyResults.Verify(proxy => proxy.SendAsync("UpdateCurrentQuestionProgress", It.IsAny<ActiveQuestionModel>(), default(CancellationToken)), Times.Once());

【问题讨论】:

  • 异常消息说明了一切:扩展方法上的验证无效。 Moq 不适用于扩展方法。
  • 从文档中接口的定义看来,您必须模拟/验证 SendCoreAsync docs.microsoft.com/en-us/dotnet/api/…
  • 既然您指出了这一点,那么该消息就有意义了。我不清楚问题在于它是仅来自消息的扩展方法。谢谢!

标签: c# unit-testing .net-core moq asp.net-core-signalr


【解决方案1】:

原来我误解了错误消息,问题是IClientProxy.SendAsync() 是一种扩展方法,而 Moq 显然不喜欢那样。可以改用SendCoreAsync(),但您始终必须将数组作为参数传递,即使您只想发送一个对象或根本不想发送任何数据。

归功于 NKosi(见问题 cmets)

【讨论】:

    猜你喜欢
    • 2020-06-29
    • 1970-01-01
    • 2015-12-18
    • 1970-01-01
    • 2012-06-03
    • 2019-07-20
    • 2016-02-19
    • 1970-01-01
    • 2018-12-27
    相关资源
    最近更新 更多