Ways to mock SignalR Clients.Group in unit test

2019-04-16 08:25发布

I'm writing mock test cases for SignalR application. I just started with the help of Unit Testing SignalR Applications, but my requirement is little bit different that example shown there. Following is the code I have done after googling.

SignalRHub

public class HubServer : Hub
{
    [HubMethodName("SendNofication")]
    public void GetNofication(string message)
    {
        try
        {
            Clients.Group("Manager").BroadCast(message);
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
    }        
}

Unit Test

public interface IClientContract { }

[TestMethod]
public void GetNoficationTest()
{
    var hub = new HubServer();
    var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
    hub.Clients = mockClients.Object;
    var all = new Mock<IClientContract>();
    string message = "Message to send";

    mockClients.Setup(m => m.Group("Manager")).Returns(message);
    mockClients.Setup(m => m.All).Returns(all.Object);

    hub.GetNofication("Mock call to SingalR hub");
    all.VerifyAll();
}

I'm beginner in Unit Test application, just want to confirm if this is right way to mock SignalR Groups.

1条回答
Juvenile、少年°
2楼-- · 2019-04-16 09:01

Using examples from Microsoft.AspNet.SignalR.Tests

Hubs Group Are Mockable

The client contract needs to be updated with the necessary methods. In this case you will have to add Broadcast method to match how it is called in the Hub

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

Next arrange the test by setting up the dependencies for the hub and exercise the method under test.

[TestMethod]
public void _GetNoficationTest() {
    // Arrange.
    var hub = new HubServer();
    var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
    var groups = new Mock<IClientContract>();
    var message = "Message to send";
    var groupName = "Manager";

    hub.Clients = mockClients.Object;
    groups.Setup(_ => _.Broadcast(message)).Verifiable();
    mockClients.Setup(_ => _.Group(groupName)).Returns(groups.Object);

    // Act.
    hub.GetNofication(message);

    // Assert.
    groups.VerifyAll();
}

Another option would be to fake the group using an ExpandoObject given that Clients.Group in this instance returns dynamic

[TestMethod]
public void _GetNoficationTest_Expando() {
    // Act.
    var hub = new HubServer();
    var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
    dynamic groups = new ExpandoObject();
    var expected = "Message to send";
    string actual = null;
    var groupName = "Manager";
    bool messageSent = false;

    hub.Clients = mockClients.Object;
    groups.Broadcast = new Action<string>(m => {
        actual = m;
        messageSent = true;
    });
    mockClients.Setup(_ => _.Group(groupName)).Returns((ExpandoObject)groups);

    // Act.
    hub.GetNofication(expected);

    // Assert.
    Assert.IsTrue(messageSent);
    Assert.AreEqual(expected, actual);
}
查看更多
登录 后发表回答