C# 异步 Socket 编程

8

是否可能对异步套接字编程进行单元测试(使用c#)?请提供一些样本单元测试代码。


@user919426,您声称答案“陈旧”,并指出微软文档使用Socket而不是Stream。然而,这些只是不同的抽象。您可以将Socket包装在NetworkStream中,将其转换为流。Socket的文档还建议使用TCPClient,它会给您提供一个Stream。如果我的下面的答案有什么过时的地方,那就是使用BeginWrite/EndWrite而不是更现代的WriteAsync。 - Wim Coenen
嗨@WimCoenen,请不要介意。老的意思是APM不再是异步TCP的推荐模式。现在建议使用async/await(https://github.com/dotnet/core/issues/4828#issuecomment-643694377)。微软文档已经过时,基于旧的APM模式。我已经得到了答案。赏金已经没有用处了。 - tinonetic
1个回答

9
我假设您正在测试自己编写的某个使用.NET流的类,我们将其称为“MessageSender”。请注意,没有理由对.NET流本身进行单元测试,这是微软的工作。您不应该单元测试.NET框架代码,只需测试自己的代码。
首先,请确保“MessageSender”使用的流是通过注入的。不要在类内部创建它,而是将其作为属性值或构造函数参数接受。例如:
public sealed class MessageSender
{
   private readonly Stream stream;

   public MessageSender(Stream stream)
   {
      if (stream == null)
         throw new ArgumentNullException("stream");
      this.stream = stream;
   }

   public IAsyncResult BeginSendHello(AsyncCallback callback, object state)
   {
      byte[] message = new byte[] {0x01, 0x02, 0x03};
      return this.stream.BeginWrite(
         message, 0, message.Length, callback, state);
   }

   public void EndSendHello(IAsyncResult asyncResult)
   {
      this.stream.EndWrite(asyncResult);
   }
}

现在是一个示例测试:您可以测试BeginSendHello是否在流上调用BeginWrite并发送正确的字节。我们将模拟流并设置期望以验证此操作。在此示例中,我使用RhinoMocks框架。

[Test]
public void BeginSendHelloInvokesBeginWriteWithCorrectBytes()
{
   var mocks = new MockRepository();
   var stream = mocks.StrictMock<Stream>();
   Expect.Call(stream.BeginWrite(
      new byte[] {0x01, 0x02, 0x03}, 0, 3, null, null));
   mocks.ReplayAll();

   var messageSender = new MessageSender(stream);
   messageSender.BeginSendHello(null, null);

   mocks.VerifyAll();
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接