单元测试SignalR集线器(Unittest SignalR Hubs)

2019-07-29 15:00发布

我想测试我的SignalR中心,什么是最好的方法呢?

可能的解决方案我曾经想过到目前为止:

  • 创建一个可测试中心
  • 抽象逻辑到单独的类
  • 硒(想测试更小的单位)
  • 抑或是一些SignalR测试功能忽略

目前使用SignalR 0.4,和NUnit的测试框架。

Answer 1:

此链接显示了如何使用单元起订量测试SignalR毂方法。 你嘲笑了程序存储库,客户,环境和调用者。 下面是从网站的代码,我做了一些小的改动,使其与最新的SignalR工作:

public class TestableChatHub : ChatHub  
{  
 public Mock<IChatRepository> MockChatRepository { get; private set; }

 public TestableChatHub(Mock<IChatRepository> mockChatRepository)  
   : base(mockChatRepository.Object)  
 {
   const string connectionId = "1234";  
   const string hubName = "Chat";  
   var mockConnection = new Mock<IConnection>();  
   var mockUser = new Mock<IPrincipal>();  
   var mockCookies = new Mock<IRequestCookieCollection>();

   var mockRequest = new Mock<IRequest>();  
   mockRequest.Setup(r => r.User).Returns(mockUser.Object);  
   mockRequest.Setup(r => r.Cookies).Returns(mockCookies.Object);

   Clients = new ClientProxy(mockConnection.Object, hubName);  
   Context = new HubCallerContext(mockRequest.Object, connectionId);

   var trackingDictionary = new TrackingDictionary();  
   Caller = new StatefulSignalProxy(
        mockConnection.Object, connectionId, hubName, trackingDictionary);  
 }  
} 

然后,该网站显示,你可以使用这个可测试中心编写单元测试:

   [TestClass]  
   public class ChatHubTests  
   {  
     private TestableChatHub _hub;

     public void SetUpTests()  
     {  
       _hub = GetTestableChatHub();  
     }

     [Test]  
     public void ExampleTest()  
     {  
       SetUpTests();
       const string message = "test";  
       const string connectionId = "1234";

       var result = _hub.Send(message);

       _hub.MockChatRepository.Verify(r => r.SaveMessage(message, connectionId));
       Assert.IsTrue(result);  
     }

     private TestableChatHub GetTestableChatHub()  
     {  
       var mockRepository = new Mock<IChatRepository>();  
       mockRepository.Setup(m => m.SaveMessage(
            It.IsAny<string>(), It.IsAny<string())).Returns(true);  
       return new TestableChatHub(mockRepository);  
     }  
   }  


Answer 2:

这是很简单的创建到使用几个巧妙的技巧的单元测试SignalR枢纽。 有一点要注意的是,SignalR使用dynamic这可能不是你的模拟框架(我用的支持类NSubstitute )。

public class ProjectsHub: Hub
{
   public void AddProject(string id)
   {
      Clients.All.AddProject(id);
   }
}

[TestFixture]
public class ProjectsHubTests
{
    // Operations that clients might receive
    // This interface is in place in order to mock the
    // dynamic object used in SignalR
    public interface ISignals
    {
        void AddProject(string id);
    }

    [Test]
    public void AddProject_Broadcasts()
    {
        // Arrange
        ProjectsHub hub = new ProjectsHub();
        IHubCallerConnectionContext clients = 
                Substitute.For<IHubCallerConnectionContext>();
        ISignals signals = Substitute.For<ISignals>();
        SubstituteExtensions.Returns(clients.All, signals);
        hub.Clients = clients;

        // Act
        hub.AddProject("id");

        // Assert
        signals.Received(1).AddProject("id");
    }
}

改写本使用例如起订量应该是相当简单的。



Answer 3:

来自这个问题前一段时间,但我会尽我所能反正回答。

如果你在实际的HUB类有很多逻辑的,这肯定会是有意义的抽象逻辑到一个单独的类。 我也同样为我SignalR供电多人演示。 应在集线器类本身去的唯一行为是一个有关消息。 所有进一步行动,应委托。

注:这是非常喜欢在ASP .NET MVC控制器的设计准则:保持你的控制器小,委托真正的工作。

如果你想集成测试与SignalR实际做了一些工作,硒的webdriver将是一个不错的选择。 但是,你可能需要做一些调整,以获得SignalR消息在测试的情况下完美地工作。 做谷歌搜索“signalr硒”(不带引号)即可开始步入正轨。

关于自动化测试的一些相关博客文章为SignalR => 在这里和这里



Answer 4:

随着SignalR 2.0,你可以这样来做:

// Arrange
var hub = new CodeInteractivePreviewHub();
var mockClients = new Mock<IHubCallerConnectionContext<dynamic>>();
hub.Clients = mockClients.Object;
dynamic all = new ExpandoObject();
mockClients.Setup(m => m.All).Returns((ExpandoObject)all);

// Act
var allSourceCodes = hub.InitiateCommunication(); //Change this line to your Hub's method 

// Assert
Assert.IsNotNull(allSourceCodes);


Answer 5:

这是修改Iarsm的答案的版本,和的xUnit起订量工作。

using Microsoft.AspNet.SignalR;
using Microsoft.AspNet.SignalR.Hubs;
using Moq;
using Xunit;

namespace TestLibrary {
public class ProjectsHub : Hub {
    public void AddProject(string id) {
        Clients.All.AddProject(id);
    }
}

public class ProjectsHubTests {
    // Operations that clients might receive
    // This interface is in place in order to mock the
    // dynamic object used in SignalR
    public interface ISignals {
        void AddProject(string id);
    }

    [Fact]
    public void AddProject_Broadcasts() {
        // Arrange
        ProjectsHub hub = new ProjectsHub();
        var clients = new Mock<IHubCallerConnectionContext<dynamic>>();
        var signals = new Mock<ISignals>();
        hub.Clients = clients.Object;

        signals.Setup(m => m.AddProject(It.Is<string>(s => s == "id"))).Verifiable();
        clients.Setup(m => m.All).Returns(signals.Object);

        // Act
        hub.AddProject("id");

        // Assert
        signals.VerifyAll();
    }
}

}



Answer 6:

我个人认为最好的办法是给出- http://www.asp.net/signalr/overview/testing-and-debugging/unit-testing-signalr-applications



文章来源: Unittest SignalR Hubs