Search code examples
multithreadingunit-testingasync-awaitxunit

How can I to correctly run an async thread in a test method?


I have this test that needs to run the RunWebSocket thread to make sure the SendAsync was received by my websocket. This works, but I am getting compiler warning CS4014. Of course, I do not like warnings, so instead of ignoring it, I want to do it "right".

[Fact]
public async void CabinetTagPushed_ShouldSendBroadcastToWebSocket()
{
    // arrange
    var websocket = Substitute.For<IWebSocket>();
    restinterface.RunWebSocket(websocket);

    // act
    restinterface.Cabinet_OnTagPushed(null, new TagEventArgs());

    // assert
    await websocket.Received().SendAsync(Arg.Any<ArraySegment<byte>>(), WebSocketMessageType.Text, false, CancellationToken.None);

    // this will end the RunWebSocket thread
    websocket.CloseStatus = WebSocketCloseStatus.NormalClosure;
}

How can I create a test that kicks off an async thread correctly?


Solution

  • First, your unit test method must be async Task, not async void.

    Next, it's generally a good idea to await all tasks, to ensure you observe exceptions. Assuming the warning is on the RunWebSocket call, then that would look like this:

    [Fact]
    public async Task CabinetTagPushed_ShouldSendBroadcastToWebSocket()
    {
        // arrange
        var websocket = Substitute.For<IWebSocket>();
        var runTask = restinterface.RunWebSocket(websocket);
    
        // act
        restinterface.Cabinet_OnTagPushed(null, new TagEventArgs());
    
        // assert
        await websocket.Received().SendAsync(Arg.Any<ArraySegment<byte>>(), WebSocketMessageType.Text, false, CancellationToken.None);
    
        // this will end the RunWebSocket thread
        websocket.CloseStatus = WebSocketCloseStatus.NormalClosure;
    
        await runTask;
    }