Warm tip: This article is reproduced from stackoverflow.com, please click
.net-core asp.net-core asp.net-core-signalr signalr xunit

Mocking a Context.ConnectionId for Unit Testing Signalr .NetCore Messaging Hubs

发布于 2020-03-27 10:20:51

My question is regarding getting a context.connection ID value to insert into one of my methods when i'm unit testing my Signalr hubs in .Net CORE. My method looks like this in my test class:

[Fact]
    public async Task TestWorkstationCreation()
    {
        Mock<IHubCallerClients<IWorkstation>> mockClients = new Mock<IHubCallerClients<IWorkstation>>();
        Mock<IWorkstation> mockClientProxy = new Mock<IWorkstation>();
        mockClients.Setup(clients => clients.All).Returns(mockClientProxy.Object);
        _workstationHub.Clients = mockClients.Object;
        await _workstationHub.RegisterWorkstation("WKS16", "Ready", new Dictionary<string, string> {{"OS", "Windows 10"}, {"Exam", "GRE, TOEFL"}});
        mockClientProxy.Verify(c => c.WorkstationRegistered(It.IsAny<WorkstationDataModel>(), It.IsAny<string>()), Times.AtLeastOnce);
    }

In my hub class, this is the method:

public async Task RegisterWorkstation(string id, string status, Dictionary<string, string> capabilities)
    {
        _logger.LogInformation(
            "Registering a Workstation with id: {id}, status: {status}, and capabilities: {capabilities}",
            id, status, string.Join(",", capabilities));
        var workstationAdded = AddWorkstation(id, status, capabilities, Context.ConnectionId);
        var message = workstationAdded == null
            ? $"A workstation with the id: {id} already exists!"
            : $"A workstation with the id: {id}, status: {status}, and capabilities: {string.Join(",", capabilities)} " +
              "was added to the current list of workstations available.";
        await Clients.All.WorkstationRegistered(workstationAdded, message);
    }

When testing, it throws an Object reference not set null pointer exception at Context.ConnectionId. Is there someway to mock a Context.Connection Id that can be used?

Questioner
Spartan 117
Viewed
296
Spartan 117 2019-07-09 02:58

I ultimately ended up doing this for the Unit Test and it worked

[Fact]
    public async Task TestWorkstationCreation()
    {
        Mock<IHubCallerClients<IWorkstation>> mockClients = new Mock<IHubCallerClients<IWorkstation>>();
        Mock<IWorkstation> mockClientProxy = new Mock<IWorkstation>();
        Mock<HubCallerContext> mockClientContext = new Mock<HubCallerContext>();
        mockClients.Setup(clients => clients.All).Returns(mockClientProxy.Object);
        mockClientContext.Setup(c => c.ConnectionId).Returns(Guid.NewGuid().ToString);
        _workstationHub.Clients = mockClients.Object;
        _workstationHub.Context = mockClientContext.Object;
        await _workstationHub.RegisterWorkstation("WKS16", "Ready", new Dictionary<string, string> {{"OS", "Windows 10"}, {"Exam", "GRE, TOEFL"}});
        mockClientProxy.Verify(c => c.WorkstationRegistered(It.IsAny<WorkstationDataModel>(), It.IsAny<string>()), Times.AtLeastOnce);
    }