2012-05-29 2 views
17

Mi piacerebbe testare il mio Hub in SignalR, qual è l'approccio migliore?Unittest SignalR Hub

Possibili soluzioni ho pensato finora:

  • creare un polo testabile
  • astratta logica di classe separata
  • Selenio (vorrebbe testare unità più piccole)
  • O è un po ' Le funzionalità di test SignalR sono state trascurate

Attualmente utilizzando SignalR 0.4 e NUnit come framework di test .

risposta

4

Questa domanda è di qualche tempo fa, ma farò del mio meglio per rispondere comunque.

Se si dispone di molta logica nella propria classe hub, sarebbe sicuramente logico estrapolare la logica in una classe separata. Ho fatto lo stesso per la mia demo multiplayer con SignalR-powered. L'unico comportamento che dovrebbe andare nella classe del proprio hub è quello relativo alla messaggistica. Tutte le ulteriori azioni dovrebbero essere delegate.

Nota: questo è molto simile alle linee guida per la progettazione del controller in ASP .NET MVC: mantenere i controller piccoli e delegare il lavoro reale.

Se si desidera eseguire alcuni test di integrazione con SignalR, il selenio web sarebbe una buona opzione. Ma probabilmente avrai bisogno di fare qualche aggiustamento per far funzionare perfettamente il messaggio SignalR nel contesto dei test. Fai una ricerca su google per "signalr selenium" (senza virgolette) per iniziare sulla giusta traccia.

Alcuni blogposts circa test automatizzati per SignalR =>here e here

+0

I link alla fine sono rotti :(ancora bisogno di risposte .. –

+0

ho ri-controllato i collegamenti, e sembrano funzionare. Potrebbe essere stato un problema temporaneo con quel sito Web. –

+1

Sì, Jasmine (o Selenium) funzionerebbe.Mi domando se potremmo testare lo stesso comportamento con NUnit. –

8

Questo link mostra come unità mozzo metodi di prova SignalR utilizzando Moq. Prendi in giro il respository, i client, il contesto e il chiamante. Ecco il codice dal sito, ho fatto alcune piccole modifiche per farlo funzionare con l'ultima 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); 
} 
} 

Poi il sito mostra che è possibile utilizzare questo hub verificabile a scrivere unit test:

[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

Sei stato in grado di controllare http://www.bradygaster.com/doing-bdd-with-signalr-and-jasmine? Ho provato anche questo e ho potuto testare le chiamate SignalR sul lato client –

+0

No, non l'avevo visto. Dovresti postare come risposta. –

+0

.. o rivedere la risposta piuttosto che lasciarla in un commento .. –

5

E 'abbastanza semplice creare un hub SignalR di test unitario usando un paio di trucchetti. Una cosa da notare è che SignalR utilizza le classi dynamic che potrebbero non essere supportate dal proprio framework di simulazione (io 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"); 
    } 
} 

riscrittura questo esempio utilizzare Moq dovrebbe essere piuttosto semplice.

+0

Modificato per funzionare con Moq e XUnit, pubblicato come risposta. – Brent

0

Questa è la versione modificata della risposta di Iarsm, per funzionare con XUnit e 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 il SignalR 2.0 si può fare in questo modo:

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