Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ClientWebSocket and Unit Tests

Tags:

I'm using System.Net.WebSockets.ClientWebSocket in a .NET 4.7 application and are facing problems when trying to make code that depends on it testable. ClientWebSocket is a sealed class thats defines two members (Optionsand ConnectAsync) that aren't part of the abstract base class WebSocket. Hence, I cannot mock ClientWebSocket nor use WebSocket, making unit tests basically impossible.

I'm wondering if anyone either knows an alternative web socket client for .NET that is mockable (i.e. just a very thin object adapter for ClientWebSocket would be enough) or any other feasible way of testing code that depends on ClientWebSocket.

like image 619
jasper Avatar asked Jun 12 '18 09:06

jasper


1 Answers

Wrap the WebSocket in the interface you need, and then mock that interface instead

Example with abbreviated method signatures:

public interface IWebSocket
{
    Task<string> ReceiveDataAsync(...);
    Task SendDataAsync(...);
    Task CloseAsync(...);

    // Add all other methods you need from the client of the websocket
}

Then implement an adapter:

public class WebsocketAdapter : IWebSocket
{
    private readonly WebSocket _websocket

    public WebsocketAdapter(Websocket websocket)
    {
        _websocket = websocket;
    }

    public async Task<string> ReceiveDataAsync(...)
    {
        return await _websocket.ReceiveDataAsync(...);
    }

    public async Task SendDataAsync(...)
    {
        return await _websocket.SendDataAsync(...);
    }

    public async Task CloseAsync(...)
    {
        return await _websocket.CloseAsync(...);
    }
}

Now you can mock your own IWebSocket interface in your tests.

This is called a Humble Object, an object that merely wraps another object or a static method call, so you can hide it behind a mockable interface.

like image 86
Undreren Avatar answered Oct 11 '22 16:10

Undreren