How do I add Group support to a mocked Client in a

2019-02-17 19:01发布

问题:

I'm using Moq to build up a UnitTest framework for my SignalR 2.x application. I am currently mocking up my Clients by:

var mockClients = new Mock<IHubCallerConnectionContext>();
Clients = mockClients.Object;

In order to test, I need to test sending messages by Group:

Clients.Group(groupName).sendSomeMessage(message);

How do I add Group support to my mocked up Client?

回答1:

Check this: https://github.com/SignalR/SignalR/blob/release/tests/Microsoft.AspNet.SignalR.Tests/Server/Hubs/HubFacts.cs

 public void HubsGroupAreMockable()
        {
            var hub = new MyTestableHub();
            var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
            var groups = new Mock<IClientContract>();

            hub.Clients = mockClients.Object;
            groups.Setup(m => m.send(It.IsAny<string>())).Verifiable();
            mockClients.Setup(m => m.Group("test")).Returns(groups.Object);
            hub.SendGroup("test", "foo");

            groups.VerifyAll();
        }


回答2:

You could refer to this tutorial by the SingalR team.



回答3:

If you want to check that a certain group was notified you should be able to do something like this (this is SignalR 2):

public interface IClientContract
{
    void RaiseAlert(string message);
}

[Test]
public void NotifiesOnlySpecifiedGroupWhenGroupIdSent()
{
    // Adapted from code here: https://github.com/SignalR/SignalR/blob/dev/tests/Microsoft.AspNet.SignalR.Tests/Server/Hubs/HubFacts.cs

    // Arrange

    // Set up the individual mock clients
    var group1 = new Mock<IClientContract>();
    var group2 = new Mock<IClientContract>();
    var group3 = new Mock<IClientContract>();

    group1.Setup(m => m.RaiseAlert(It.IsAny<string>())).Verifiable();
    group2.Setup(m => m.RaiseAlert(It.IsAny<string>())).Verifiable();
    group3.Setup(m => m.RaiseAlert(It.IsAny<string>())).Verifiable();

    // set the Connection Context to return the mock clients
    var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
    mockClients.Setup(m => m.Group("1")).Returns(group1.Object);
    mockClients.Setup(m => m.Group("2")).Returns(group2.Object);
    mockClients.Setup(m => m.Group("3")).Returns(group3.Object);

    // Assign our mock context to our hub
    var hub = new NotificationsHub
    {
        Clients = mockClients.Object
    };

    // Act
    hub.RaiseNotificationAlert("2");

    // Assert
    group1.Verify(m => m.RaiseAlert(It.IsAny<string>()), Times.Never);
    group2.Verify(m => m.RaiseAlert(""), Times.Once);
    group3.Verify(m => m.RaiseAlert(It.IsAny<string>()), Times.Never);
}

The code above is checking that my NotificationsHub.RaiseAlert(string groupId) method is only triggered on the client side for the specific groupId I pass in.

This is the hub that's being tested:

public class NotificationsHub : Hub
{
    public void RaiseAlert(string message)
    {
        Clients.All.RaiseAlert(message);
    }

    public void RaiseNotificationAlert(string groupId)
    {
        if (groupId== null)
        {
            // Notify all clients
            Clients.All.RaiseAlert("");
            return;
        }

        // Notify only the client for this userId
        Clients.Group(groupId).RaiseAlert("");

    }
}