gpt4 book ai didi

c# - 如何为包含 ManualResetEvent.WaitOne() 的异步(套接字)代码编写单元测试?

转载 作者:行者123 更新时间:2023-11-30 18:36:57 28 4
gpt4 key购买 nike

我正在玩弄套接字服务器并尝试根据测试驱动开发模式工作。

有一个套接字创建方法的工作测试,但我的测试挂起是因为我有一个 ManualResetEvent.WaitOne() 以便我的套接字在创建另一个之前等待连接。

这是要测试的代码块:

ManualResetEvent allDone = new ManualResetEvent(false);
public void StartListening()
{
allDone.Reset();

//Inform on the console that the socket is ready
Console.WriteLine("Waiting for a connection...");

/* Waits for a connection and accepts it. AcceptCallback is called and the actual
* socket passed as AsyncResult
*/
listener.BeginAcceptTcpClient(
new AsyncCallback(AcceptCallback),
listener);

allDone.WaitOne();
}

这是卡在“networkChannel.StartListening();”处的测试方法;

[TestMethod]
public void NetworkChannel_IsAcceptingConnectionsAsynchronously()
{
ITcpClient client = MockRepository.GenerateMock<ITcpClient>();
ITcpListener listener = MockRepository.GenerateMock<ITcpListener>();
IAsyncResult asyncResult = MockRepository.GenerateMock<IAsyncResult>();

listener.Expect(x => x.BeginAcceptTcpClient(null, null)).IgnoreArguments().Return(asyncResult);
listener.Expect(x => x.EndAcceptTcpClient(asyncResult)).Return(client);

NetworkChannel networkChannel = new NetworkChannel(listener);

networkChannel.StartListening();
//Some more work... fake callback etc., verfify expectations,...
}

如果我评论所有的 manualresetevents,测试会顺利通过,但这不是解决方案,因为服务器会不断尝试创建重复的套接字 ;-)

对我有什么提示吗?将不胜感激!

问候,马丁

最佳答案

问题是,你到底想测试什么?

如果测试只是期望方法 StartListening 调用 listener.BeginAcceptTcpClient,那么最简单的解决方案是注入(inject)和模拟您的同步对象 (ManualResetEvent) 在您的 SUT 中,就像您使用非阻塞模拟对监听器所做的那样。

当你想测试阻塞时,你必须在你的测试中启动另一个线程before调用listener.BeginAcceptTcpClient,它在一些安全<之后发出ManualResetEvent信号/em> 等待时间 - 让我们说两秒钟 - 但这甚至可能还不够,所以你的测试结果可能不像 Grzegorz 评论的那样是确定性的。

线程和单元测试可能会变得有些复杂。

关于c# - 如何为包含 ManualResetEvent.WaitOne() 的异步(套接字)代码编写单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13283480/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com