如何在单元测试中处理后台线程中的异常? [英] How to handle exception in a background thread in a unit test?

查看:114
本文介绍了如何在单元测试中处理后台线程中的异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在编写一个单元测试套件来测试TCP/IP通信库.

I'm writing a unit test suite to test a TCP/IP communication library.

当我使用BeginAcceptClient和EndAcceptClient时,消息是在后台线程中接收的.

As I'm using BeginAcceptClient and EndAcceptClient, the messages are received in a background thread.

收到消息后,我会对它执行一些声明,但是如果任何声明失败,VSTestHost.exe将崩溃.

After a message is received, I perform some assertions on it, but if any assertion fails, the VSTestHost.exe crashes.

我搜索了一下,发现其事实是Assert异常正在后台线程中抛出.

I googled a bit and found out its the fact the Assert exceptions are being thrown in a background thread.

我正在做的示例代码,仅用于说明:

A sample code of what I am doing, just to ilustrate:


public void TestFooMessage() {
    Server.OnReceive += (s, e) => {
        Assert.IsInstanceOfType(e.Message, typeof(Foo));
    };

    var message = new Foo();
    Client.Send(message);
}

有人知道如何使它按预期工作:记录断言并继续正常运行?

Does anyone know how to make it work as expected: Log the assertion and continues running normally?

推荐答案

您不应在后台线程中编写声明"(例如:后台事件处理程序),因为测试框架无法处理此问题.您只应在此处收集值.您可以使用AutoResetEvents同步实例的主线程.将值写入字段,在主线程中声明字段.

You should not write the Asserts in the background thread (say: the background event handler), because the test framework can not handle this. You should only gather values there. You can synchronize the main thread for instance using AutoResetEvents. Write the values into fields, assert the fields in the main thread.

如果消息永远不会进入,则需要超时.

If the messages are never coming in, you need a timeout.

一点伪代码(实际上不是那个伪代码):

A bit pseudo code (actually not that pseudo):

private AutoResetEvent ReceiveEvent = new AutoResetEvent(false);
private EventArgs args;
private bool ReceiveCalled = false;

// event handler with some argument
private void Receive(object sender, EventArgs args)
{
  // get some arguments from the system under test
  this.args= args;

  // set the boolean that the message came in
  ReceiveCalled = true;

  // let the main thread proceed
  ReceiveEvent.Set();
}

[TestMethod]
public void Test()
{
  // register handler
  Server.OnReceive += Receive;

  var message = new Foo();
  Client.Send(message);

  // wait one second for the messages to come in
  ReceiveEvent.WaitOne(1000);

  // check if the message has been received
  Assert.IsTrue(
    ReceiveCalled, 
    "AcceptClientReceived has not been called");

  // assert values from the message
  Assert.IsInstanceOfType(args.Message, typeof(Foo))    
}

顺便说一句:您仍然可以将处理程序编写为lambda表达式,甚至可以通过使用局部变量来避免使用字段.但是,如果所有内容都在一个方法中,则可能很难阅读.

By the way: you still can write the handler as a lambda expression and even avoid the fields by using local variables. But it could be harder to read if everything is in a single method.

这篇关于如何在单元测试中处理后台线程中的异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆