【问题标题】:Unit Test method that blocks thread阻塞线程的单元测试方法
【发布时间】:2019-10-17 14:34:49
【问题描述】:

在等待某事并阻塞线程的方法上进行 UnitTest 的最佳方法是什么? 我想测试该方法是否调用了另一个方法,但显然测试永远不会结束,因为线程等待另一个事件。我正在使用 C#、xUnit 和 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();
}

【问题讨论】:

  • Mock.Verify 呢?
  • 一般是的,但是 Mock.Verify 对我的阻塞线程问题没有帮助
  • 为什么不触发你的线程正在等待的事件呢?那你就不用异常爆栈了,用Verify就可以测试副作用了...?
  • 我认为这也仅适用于超时以允许该方法执行。而且它要复杂得多,因为它正在等待套接字的响应。这意味着更多的依赖。您当然可以模拟,但正如@MikeLimaSierra 所说,处理异常可以更清楚地了解意图。

标签: c# unit-testing mocking xunit.net


【解决方案1】:

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

虽然超时也可以正常工作,但它会产生相同的效果,但实际上只是增加了运行测试所需的时间。

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

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

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

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

【讨论】:

  • 如果这个答案解决了你的问题,请采纳。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-07
  • 1970-01-01
  • 1970-01-01
  • 2019-05-22
  • 1970-01-01
相关资源
最近更新 更多