我有一个简单的集线器信号集线器集合,负责跨应用程序发送通知,主要由用户名和消息组成,我一直在尝试使用单元测试创建一个 Xunit 测试脚本,该脚本能够测试服务器端集线器方法以及每个集线器连接的一个单元测试中的客户端集线器方法,我没有运气,我在线阅读的大部分内容似乎都已过时且无效,我正在努力处理空引用并创建一些不可行的东西真正关于使用模拟对象......现在几乎所有集线器都只是发送字符串,在使用起订量进行单元测试 SignalR 时,有人有任何经验或解决方案吗?请参阅下面的代码,了解如何集线器通常会工作...
服务器中心
public async Task SendMessage(string userName, string message)
{
await Clients.All.SendAsync("OnMessageReceived", userName, message);
}
客户中心
connection.on("OnMessageReceived", function (userName, message) {
console.log("this is the user Name =>", userName)
console.log("this is the user Message =>", message)
})
下面使用 xunit 测试的测试脚本,我尝试了许多不同的方法来制作一个简单的起订量和单元测试来测试上面的两个集线器,但无法获得任何东西来测试或成功工作。我查看了 MS 文档并在线尝试了一些不同的脚本,但无法将任何内容作为一个单元测试来在一个测试中测试两个集线器连接。我认为需要为 void 方法设置一些东西,但不确定如何设置。
[Fact]
public async Task HubsAreMockableVia()
{
//.........Test Mock connection works and is verified, but uncertain this is a good test
//var mock = new Mock<CreateConnectionHub>();
//mock.Object.SendMessage("TestUser", "TestMessage");
//mock.Verify();
Mock<IHubCallerClients> mockClients = new Mock<IHubCallerClients>();
Mock<IClientProxy> mockClientProxy = new Mock<IClientProxy>();
mockClients.Setup(clients => clients.All).Returns(mockClientProxy.Object);
CreateConnectionHub testhub = new CreateConnectionHub()
{
Clients = mockClients.Object
};
await testhub.SendMessage("hello","user");
mockClients.Verify(clients => clients.All, Times.Once);
mockClientProxy.Verify(
clientProxy => clientProxy.SendAsync(
"OnMessageReceived",
It.IsAny<string>(),
It.IsAny<string>(),
default(CancellationToken)),
Times.Once);
}
退货: 信息: System.NotSupportedException:不支持的表达式:clientProxy => clientProxy.SendAsync(“OnMessageReceived”,It.IsAny(),It.IsAny(),CancellationToken) 扩展方法(此处:ClientProxyExtensions.SendAsync)不得在设置/验证表达式中使用。
我尝试过几种方法来修改此问题,但没有找到解决方法,谢谢您的宝贵时间。
以下代码修复运行一个干净的测试并通过,它允许 NUnit 检查 testhub 发送消息是否按要求接收两个字符串变量。
等待 testhub.SendMessage("hello","user"); mockClients.Verify(clients =>clients.All, Times.Once);
mockClientProxy.Verify(
clientProxy => clientProxy.SendAsync(
"OnMessageReceived",
It.Is<object[]>(o => o != null && o.Length == 2),
default(CancellationToken)),
Times.Once);