如何单元测试客户端网络代码?

时间:2011-03-01 16:13:31

标签: c# multithreading unit-testing client-server

我正在研究一个侦听TCP连接的网络代码,解析传入的数据并引发相应的事件。当然,为了避免阻塞应用程序的其余部分,监听和解析是在后台工作程序中执行的。当试图对这段代码进行单元测试时,我遇到的问题是,当网络代码比单元测试有更多的工作要做时,单元测试在适配器有机会引发事件之前完成,因此测试失败。 / p>

适配器类:

public class NetworkAdapter : NetworkAdapterBase //NetworkAdapterBase is just an abstract base class with event definitions and protected Raise... methods.
{
    //Fields removed for brevity.

    public NetworkAdapter(TcpClient tcpClient)
    {
        _tcpConnection = tcpClient;

        //Hook up event handlers for background worker.
        NetworkWorker.DoWork += NetworkWorker_DoWork;

        if (IsConnected)
        {
            //Start up background worker.
            NetworkWorker.RunWorkerAsync();
        }
    }

    private void NetworkWorker_DoWork(object sender, DoWorkEventArgs e)
    {
        while (IsConnected)
        {
            //Listen for incoming data, parse, raise events...
        }
    }
}

尝试测试代码:

[TestMethod]
public void _processes_network_data()
{
    bool newConfigurationReceived = false;

    var adapter = new NetworkAdapter(TestClient); //TestClient is just a TcpClient that is set up in a [TestInitialize] method.

    adapter.ConfigurationDataReceived += (sender, config) =>
    {
        newConfigurationReceived = true;
    };

    //Send fake byte packets to TestClient.

    Assert.IsTrue(newConfigurationReceived, "Results: Event not raised.");
}

我该如何尝试测试这类东西?

谢谢,

詹姆斯

4 个答案:

答案 0 :(得分:6)

嗯,首先,这不是严格的“单元测试”;您的测试取决于具有副作用的体系结构层,在这种情况下传输网络数据包。这更像是一次集成测试。

那就是说,你的单位测试可以睡一定数量的毫秒,正如托尼所说。您还可以查看是否可以获得后台工作程序的句柄,并加入它,这将导致单元测试等待后台工作程序完成所需的时间。

答案 1 :(得分:2)

你可以等待一段时间,然后运行断言,因此:

//Send fake byte packets to TestClient
Thread.Sleep(TIMEOUT);
Assert.IsTrue(newConfigurationReceived, "Results: Event not raised.");

其中TIMEOUT是您要等待的毫秒数。

答案 2 :(得分:2)

你可以使用一些超时,但是一如既往应该确定你的测试总是会超时的超时持续时间,但仍然没有太慢的测试速度?

我只是简单地测试解析代码。这可能是你将遇到最多错误的地方,也是你最需要进行单元测试的地方。它很容易测试!

然后对于正在侦听套接字的代码......那么你可能会有bug ...但是如果它只是将数据分派给一个函数/类,我不确定你真的需要测试它。如果你想要非常彻底,如果客户端和服务器之间的连接丢失,你将如何测试你的类表现良好?

答案 3 :(得分:2)

在我们的单元测试中,我们使用.NET 4的并行化库。你可以说:

Parallel.Invoke(() => Dosomething(arguments), () => DosomethingElse(arguments));

框架将负责将这些操作产生为不同的线程,在许多线程中执行它们,这些线程对于您正在处理的特定进程是理想的,然后加入它们以便下一条指令不会执行直到它们已经完成了。

但是,您可能无法直接访问该主题。相反,您希望等到调用给定的回调方法。您可以使用AutoResetEvent或ManualResetEvent来完成此任务。

请参阅Unit testing asynchronous function

相关问题