2014-04-24 15 views
6

Tôi đang sử dụng SignalR trong một dự án MVC5. Tôi đang thực hiện cuộc gọi trong bộ điều khiển như thế này:Tôi nên giả sử SignalR HubContext trong Bộ điều khiển để kiểm tra đơn vị như thế nào?

private Microsoft.AspNet.SignalR.IHubContext blogHubContext = Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager.GetHubContext<BlogHub>(); 
blogHubContext.Clients.All.addNewBlogToPage(RenderPartialViewToString("Blog", model)); 

Tôi đang cố gắng đơn vị kiểm tra các hành động trong bộ điều khiển này. Các bài kiểm tra đơn vị đã hoạt động tốt cho đến khi tôi thêm chức năng SignalR. Bây giờ tôi đang cố gắng tìm ra cách chế tạo HubContext. Tôi có 2 khả năng.

  1. tôi thiết lập các trung tâm trong các nhà xây dựng vì vậy tôi có một cái gì đó như sau:

    private Microsoft.AspNet.SignalR.IHubContext blogHubContext; 
    public BlogController(Microsoft.AspNet.SignalR.IHubContext topicHub = null){ 
        blogHubContext = (blogHub != null) ? blogHub : Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager.GetHubContext<BlogHub>(); 
    } 
    

    Sau đó, tôi bằng cách nào đó có thể thử các HubContext và gửi nó thông qua bộ điều khiển khi tôi tạo ra nó trong các đơn vị kiểm tra. Cho đến nay tôi chỉ có mặc dù điều này:

    Mock<IHubContext> blogHub = new Mock<IHubContext>(); 
    

    (Lưu ý:. Tôi đã đơn giản hóa mọi thứ để tập trung vào chỉ phía SignalR thứ Ngoài ra còn có kho được sử dụng trong bộ điều khiển vv)

  2. Ngoài ra, tôi nghĩ về việc tạo một lớp khác để bọc trung tâm, và sau đó chỉ cần gọi các hàm từ đây để thực hiện các cuộc gọi đến hub. Điều này tôi thấy là dễ dàng hơn nhiều để thử nghiệm cho các bài kiểm tra đơn vị của tôi, nhưng không chắc chắn nếu đó là một ý tưởng tốt.

Hướng được đánh giá cao. Hay cả hai đều có thể chấp nhận được? Cảm ơn.

+0

tôi thích lựa chọn 1 vì bạn không cần một lớp thêm lớp wrapper mà không thêm bất kỳ chức năng. –

+0

@ AD.Net Cảm ơn. Trong trường hợp đó, bất kỳ ý tưởng nào làm thế nào tôi có thể đi về mocking các trung tâm cho các chức năng tôi đang sử dụng. Tôi đã cố gắng để làm việc ra làm thế nào để làm điều đó dẫn tôi suy nghĩ về các tùy chọn thứ hai. – AndrewPolland

+0

Bạn có quen với chế nhạo nói chung không? Mocking một trung tâm signalr có vẻ như nó chỉ là về giống như chế giễu bất cứ điều gì khác. –

Trả lời

1

Cập nhật, vui lòng xem mã này, tôi đang căn cứ vào mẫu MVC mặc định này. Không cần một lớp bao bọc.

public class HomeController : Controller 
{ 
    private readonly IHomeHub _hub; 

    public HomeController(IHomeHub hub) 
    { 
     _hub = hub; 
    } 

    public ActionResult Index() 
    { 
     _hub.Hello(); 
     return View(); 
    } 
} 

public interface IHomeHub 
{ 
    void Hello(); 
} 

public class HomeHub : Hub, IHomeHub 
{ 
    public void Hello() 
    { 
     Clients.All.hello(); 
    } 
} 

cho unit tests:

[TestMethod] 
public void Index() 
{ 
    var mockHub = new Mock<IHomeHub>(); 
    // Arrange 
    HomeController controller = new HomeController(mockHub.Object); 

    // Act 
    ViewResult result = controller.Index() as ViewResult; 

    // Assert 
    Assert.IsNotNull(result); 
    mockHub.Verify(h=>h.Hello(), Times.Once); 
} 
+0

Điều này có vẻ thực sự tốt. Nhưng tôi không thể làm cho nó hoạt động do chỉ có thể gọi một hàm từ hub (bên trong bộ điều khiển) nếu nó là tĩnh, mà nó không thể được khi thực hiện từ một giao diện. Vì vậy, sự hiểu biết của tôi anyway. – AndrewPolland

+0

xin lỗi nó không rõ ràng, phương pháp Hello không phải là tĩnh trên lớp Hub và bạn có thể gọi nó từ bộ điều khiển. –

+0

Xin lỗi, một phần của vấn đề với đó là kết thúc của tôi. Tĩnh không cần thiết như tôi đã suy nghĩ. Tuy nhiên, khi gọi phương thức Hello từ bộ điều khiển, máy khách không thể được gọi theo cách bạn có. Nó tạo ra lỗi sau: Sử dụng một thể hiện Hub không được tạo bởi HubPipeline không được hỗ trợ. – AndrewPolland

Các vấn đề liên quan