Unit Testing SignalR Applications
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
- Visual Studio 2013
- .NET 4.5
- SignalR version 2
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.
Install the XUnit Runner extension for Visual Studio 2013.
Either complete the Getting Started tutorial, or download the completed application from MSDN Code Gallery.
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.
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.
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 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
Create the test file. Right-click the TestLibrary project and click Add..., Class. Name the new class Tests.cs.
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, assigndynamic
for the type parameter.) TheIHubCallerConnectionContext
interface is the proxy object with which you invoke methods on the client. ThebroadcastMessage
function is then defined for the mock client so that it can be called by theChatHub
class. The test engine then calls theSend
method of theChatHub
class, which in turn calls the mockedbroadcastMessage
function.Build the solution by pressing F6.
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.
Verify that the test passed by checking the lower pane in the Test Explorer window. The window will show that the test 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.
Complete steps 1-7 in the Unit testing with Dynamic tutorial above.
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 theMock
object, of type IHubCallerConnectionContext (in SignalR 2.1, assigndynamic
for the type parameter.) TheIHubCallerConnectionContext
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 thebroadcastMessage
method, which in turn is invoked by calling theSend
method on the hub.Build the solution by pressing F6.
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.
Verify that the test passed by checking the lower pane in the Test Explorer window. The window will show that the test passed.