阻塞线程的单元测试方法

Unit Test method that blocks thread

什么被认为是对等待某些东西并阻塞线程的方法进行单元测试的最佳方法? 我想测试该方法是否调用另一个方法,但显然测试永远不会结束,因为线程等待另一个事件。我正在使用 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();
}

就我个人而言,我会像您在示例中那样抛出特定异常。 这是最简单的正确方法,也是任何 reader 测试中最明显的方法。

虽然超时也一样有效,但它会产生相同的效果,但实际上只会增加 运行 测试所需的时间。

你的测试的读者可能想知道你为什么首先使用超时。 可能不太清楚,为什么使用特定间隔等待完成。

我也宁愿不抛出 System.Exception,而是抛出一个特定的自定义异常,如 DummyException,以表明它纯粹用于测试,与方法调用背后的实际行为无关。

我也更喜欢这个,而不是你的 try-catch 块,但这有点个人偏好。

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