Метод модульного теста, который блокирует поток - PullRequest
1 голос
/ 17 октября 2019

Что считается лучшим способом сделать UnitTest для метода, который ожидает чего-то и блокирует поток? Я хочу проверить, вызывает ли метод другой метод, но очевидно, что тест никогда не заканчивается, потому что поток ожидает другого события. Я использую C #, xUnit и Mock. Мне пришла в голову идея создать исключение с помощью mock при вызове метода для завершения блока. Другой идеей было бы работать с таймаутом, но это также звучит неправильно. Что вы считаете хорошей практикой в ​​этом случае?

[Fact]
public void Connect_ConnectAsync_MethodCalled()
{
    // Arrange
    var socketMock = new Mock<IHsmsSocket>();
    socketMock.Setup(x => x.ConnectAsync(It.IsAny<SocketAsyncEventArgs>())).Throws(new Exception("Method called"));

    int bufferSize = 5000;
    int port = 5000;
    IPAddress ip = IPAddress.Parse("0.0.0.0");
    SocketClient client = new SocketClient(socketMock.Object, bufferSize);

    IPEndPoint endPoint = new IPEndPoint(ip, port);

    Exception ex = new Exception("Not called");

    // Act
    try
    {
        client.Connect(endPoint);
    }
    catch (Exception e)
    {
        ex = e;
    }

    // Assert
    Assert.Equal("Method called", ex.Message);

    // Clean up
    client.Dispose();
}

1 Ответ

0 голосов
/ 17 октября 2019

Лично я бы выбрал конкретное исключение, как вы делаете в своем примере. Это самый простой способ получить правильную информацию, а также самый очевидный для любого читателя теста.

Хотя тайм-аут будет работать так же хорошо, он будет иметь тот же эффект, но на самом деле просто увеличит время, необходимое длязапустите ваш тест.

Читатели вашего теста могут спросить, почему вы используете тайм-аут в первую очередь. Может быть неясно, почему определенный интервал использовался для ожидания завершения.

Я бы также предпочел не бросать System.Exception, а конкретное пользовательское исключение, такое как DummyException, чтобы прояснить, что это чисто для тестированияи не имеет ничего общего с фактическим поведением, вызванным вызовом метода.

Вместо вашего блока try-catch я бы тоже предпочел это, но это своего рода личное предпочтение.

var ex = Assert.Throws<DummyException>(action);
Assert.Equal(ex.Message, "Method called");
...