2012-05-29 19 views
17

Me gustaría probar mi Hub en SignalR, ¿cuál es el mejor enfoque?Unittest SignalR Hubs

soluciones

posibles que han pensado hasta ahora:

  • crear un centro comprobable
  • lógica abstracta de clase separada
  • selenio (le gustaría probar las unidades más pequeñas)
  • O es que algunos Las características de prueba de SignalR han pasado por alto

Actualmente utilizan SignalR 0.4 y NUnit como marco de prueba .

Respuesta

4

Esta pregunta es de hace un tiempo, pero haré todo lo posible para responder de todos modos.

Si tiene mucha lógica en su clase central real, sin duda tendría sentido resumir la lógica en una clase separada. Hice lo mismo con mi demo multiplayer alimentada por SignalR. El único comportamiento que debe ir en su clase de concentrador es el relacionado con la mensajería. Todas las acciones adicionales deben ser delegadas.

Nota: Esto es muy similar a las directrices para el diseño del controlador en ASP .NET MVC: Mantenga sus controladores pequeños y delegue el trabajo real.

Si desea realizar pruebas de integración con SignalR en realidad haciendo algún trabajo, selenium webdriver sería una buena opción. Pero probablemente necesite hacer algunos ajustes para que la mensajería SignalR funcione perfectamente en el contexto de las pruebas. Haga una búsqueda en google de "signalr selenium" (sin las comillas) para comenzar en el camino correcto.

Algunos artículos de blog sobre las pruebas automatizados para SignalR =>here y here

+0

Los enlaces al final se rompen :(todavía necesitan respuestas .. –

+0

me vuelven a comprobar los enlaces, y parecen funcionar. Podría haber sido un problema temporal con ese sitio web. –

+1

Sí, Jasmine (o Selenium) funcionaría. Me pregunto si podríamos probar el mismo comportamiento con NUnit. –

8

Este link muestra cómo unidad métodos de cubo SignalR prueba utilizando Moq. Usted simula el repositorio, los clientes, el contexto y la persona que llama. Aquí está el código de la página, he hecho algunos cambios menores para que funcione con la última 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); 
} 
} 

A continuación, el sitio de muestra que se puede utilizar este centro comprobable para escribir pruebas unitarias:

[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); 
    } 
    } 
+0

¿Pudo ver http://www.bradygaster.com/doing-bdd-with-signalr-and-jasmine? Probé eso también y pude probar las llamadas de SignalR del lado del cliente –

+0

No, yo no había visto esto. Deberías publicar esto como una respuesta. –

+0

.. o revise su respuesta en lugar de dejarla en un comentario. –

5

Es muy fácil de crear para probar los concentradores SignalR usando un par de trucos. Una cosa a tener en cuenta es que SignalR usa clases dynamic que pueden no ser compatibles con su marco de burla (yo uso 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"); 
    } 
} 

reescritura de esto para usar, por ejemplo, Moq debería ser bastante simple.

+0

Modificado para que funcione con Moq y XUnit, publicado como respuesta. – Brent

0

Esta es una versión modificada de la respuesta de Iarsm, para trabajar con XUnit y MOQ.

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(); 
    } 
} 

}

2

Con la SignalR 2.0 puede hacerlo de esta manera:

// 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);