Unit Testing SignalR Applications

by Patrick Fletcher

Warning

This documentation isn't for the latest version of SignalR. Take a look at ASP.NET Core SignalR.

This article describes using the Unit Testing features of SignalR 2.

Software versions used in this topic

Questions and comments

Please leave feedback on how you liked this tutorial and what we could improve in the comments at the bottom of the page. If you have questions that are not directly related to the tutorial, you can post them to the ASP.NET SignalR forum or StackOverflow.com.

Unit testing SignalR applications

You can use the unit test features in SignalR 2 to create unit tests for your SignalR application. SignalR 2 includes the IHubCallerConnectionContext interface, which can be used to create a mock object to simulate your hub methods for testing.

In this section, you'll add unit tests for the application created in the Getting Started tutorial using XUnit.net and Moq.

XUnit.net will be used to control the test; Moq will be used to create a mock object for testing. Other mocking frameworks can be used if desired; NSubstitute is also a good choice. This tutorial demonstrates how to set up the mock object in two ways: First, using a dynamic object (introduced in .NET Framework 4), and second, using an interface.

Contents

This tutorial contains the following sections.

Unit testing with Dynamic

In this section, you'll add a unit test for the application created in the Getting Started tutorial using a dynamic object.

  1. Install the XUnit Runner extension for Visual Studio 2013.

  2. Either complete the Getting Started tutorial, or download the completed application from MSDN Code Gallery.

  3. If you are using the download version of the Getting Started application, open Package Manager Console and click Restore to add the SignalR package to the project.

    Restore Packages

  4. Add a project to the solution for the unit test. Right-click your solution in Solution Explorer and select Add, New Project.... Under the C# node, select the Windows node. Select Class Library. Name the new project TestLibrary and click OK.

    Create Test Library

  5. Add a reference in the test library project to the SignalRChat project. Right-click the TestLibrary project and select Add, Reference.... Select the Projects node under the Solution node, and check SignalRChat. Click OK.

    Add Project Reference

  6. Add the SignalR, Moq, and XUnit packages to the TestLibrary project. In the Package Manager Console, set the Default Project dropdown to TestLibrary. Run the following commands in the console window:

    • Install-Package Microsoft.AspNet.SignalR

    • Install-Package Moq

    • Install-Package XUnit

      Install Packages

  7. Create the test file. Right-click the TestLibrary project and click Add..., Class. Name the new class Tests.cs.

  8. Replace the contents of Tests.cs with the following code.

    using System;
    using Xunit;
    using SignalRChat;
    using Microsoft.AspNet.SignalR.Hubs;
    using Moq;
    using System.Dynamic;
    
    namespace TestLibrary
    {
        public class Tests
        {
            [Fact]
            public void HubsAreMockableViaDynamic()
            {
                bool sendCalled = false;
                var hub = new ChatHub();
                var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
                hub.Clients = mockClients.Object;
                dynamic all = new ExpandoObject();
                all.broadcastMessage = new Action<string, string>((name, message) => {
                    sendCalled = true;
                });
                mockClients.Setup(m => m.All).Returns((ExpandoObject)all);
                hub.Send("TestUser", "TestMessage");
                Assert.True(sendCalled);
            }
        }
    }
    

    In the code above, a test client is created using the Mock object from the Moq library, of type IHubCallerConnectionContext (in SignalR 2.1, assign dynamic for the type parameter.) The IHubCallerConnectionContext interface is the proxy object with which you invoke methods on the client. The broadcastMessage function is then defined for the mock client so that it can be called by the ChatHub class. The test engine then calls the Send method of the ChatHub class, which in turn calls the mocked broadcastMessage function.

  9. Build the solution by pressing F6.

  10. Run the unit test. In Visual Studio, select Test, Windows, Test Explorer. In the Test Explorer window, right-click HubsAreMockableViaDynamic and select Run Selected Tests.

    Screenshot showing HubsAreMockableViaDynamic selected in the Test Explorer window.

  11. Verify that the test passed by checking the lower pane in the Test Explorer window. The window will show that the test passed.

    Screenshot showing the unit test using a dynamic object has passed.

Unit testing by type

In this section, you'll add a test for the application created in the Getting Started tutorial using an interface that contains the method to be tested.

  1. Complete steps 1-7 in the Unit testing with Dynamic tutorial above.

  2. Replace the contents of Tests.cs with the following code.

    using Xunit;
    using SignalRChat;
    using Microsoft.AspNet.SignalR.Hubs;
    using Moq;
    
    namespace TestLibrary
    {
        public class Tests
        {
           
           public interface IClientContract
           {
               void broadcastMessage(string name, string message);
           }
           [Fact]
           public void HubsAreMockableViaType()
           {
               var hub = new ChatHub();
               var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
               var all = new Mock<IClientContract>();
               hub.Clients = mockClients.Object;
               all.Setup(m => m.broadcastMessage(It.IsAny<string>(), 
                    It.IsAny<string>())).Verifiable();
               mockClients.Setup(m => m.All).Returns(all.Object);
               hub.Send("TestUser", "TestMessage");
               all.VerifyAll();
           }
        }
    }
    

    In the code above, an interface is created defining the signature of the broadcastMessage method for which the test engine will create a mock client. A mock client is then created using the Mock object, of type IHubCallerConnectionContext (in SignalR 2.1, assign dynamic for the type parameter.) The IHubCallerConnectionContext interface is the proxy object with which you invoke methods on the client.

    The test then creates an instance of ChatHub, and then creates a mock version of the broadcastMessage method, which in turn is invoked by calling the Send method on the hub.

  3. Build the solution by pressing F6.

  4. Run the unit test. In Visual Studio, select Test, Windows, Test Explorer. In the Test Explorer window, right-click HubsAreMockableViaDynamic and select Run Selected Tests.

    Screenshot showing HubsAreMockableViaType selected in the Test Explorer window.

  5. Verify that the test passed by checking the lower pane in the Test Explorer window. The window will show that the test passed.

    Screenshot showing the unit test by type has passed.