Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How should I mock SignalR HubContext in Controller for Unit Testing?

I am using SignalR in an MVC5 project. I am making calls within the controller like this:

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

I am attempting to unit test the actions within this controller. The unit tests were working fine until I added the SignalR functionality. Now I am trying to work out how to mock the HubContext. I have 2 possibilities.

  1. I setup the hub in the constructor so I have something like the following:

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

    Then I can somehow mock the HubContext and send it through to the controller when I create it in the unit test. So far I only have this though:

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

    (Note: I have simplified everything to concentrate on only the SignalR side of things. There are also repositories used in the controller etc)

  2. Alternatively, I thought about creating another class to wrap the hub, and then just call functions from this to make calls to the hub. This I see as being much easier to mock for my unit tests, but not sure if it's a good idea.

Direction appreciated. Or are both acceptable ways forward? Thanks.

like image 288
AndrewPolland Avatar asked Apr 24 '14 14:04

AndrewPolland


1 Answers

Update, please see this code, I'm basing this off the default MVC template. No need for a wrapper class.

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

for 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);
}
like image 196
AD.Net Avatar answered Nov 20 '22 07:11

AD.Net