有没有人在.NET中成功模拟过Socket类?

我试图在C#中模拟出System.net.Sockets.Socket类 – 我尝试使用NUnit模拟但它不能模拟具体的类。 我也尝试过使用Rhino Mocks但它似乎使用了该类的真实版本,因为它在调用Send(byte [])时抛出了SocketException。 有没有人使用任何模拟框架成功创建和使用Socket模拟?

每当我遇到Moq的这些问题时,我最终都会创建一个接口来抽象出我无法模拟的东西。

因此,在您的实例中,您可能有一个实现Send方法的ISocket接口。 然后让你的模拟框架嘲笑。

在您的实际代码中,您将拥有这样的类

public class MySocket : ISocket { System.Net.Sockets.Socket _socket; public void MySocket(System.Net.Sockets.Socket theSocket) { _socket = theSocket; } public virtual void Send(byte[] stuffToSend) { _socket.Send(stuffToSend); } } 

不确定这是否符合您的需求,但这是一个选择。

调用Send方法时出现SocketException的原因是Send不是可覆盖的方法。 为了使RhinoMocks能够模拟属性或方法的行为,它必须在接口中定义(然后我们创建模拟关闭)或者可以覆盖。

您唯一的解决方案是创建一个可模拟的包装类(如thinkzig所示)。

我使用thinkzig建议的方法(Socket的适配器类)创建了一个示例控制台应用程序。 它使用RhinoMocks和NUnit。 你可以在这里下载它: 如何模拟System.Net.Sockets.Socket 。

上面的类只模拟你的发送方法。 这实际上嘲笑了一个Socket。 它inheritance了所有Socket,然后实现了ISocket接口。 ISocket需要实现您需要模拟的任何Socket方法或属性的签名

 //internal because only used for test code internal class SocketWrapper : Socket, ISocket { ///  /// Web Socket ///  public SocketWrapper():base(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) { } //use all features of base Socket } 

界面看起来像这样两种方法被拒绝:

 public interface ISocket { void Connect(IPAddress address, int port); int Send(byte[] buffer, int offset, int size, SocketFlags socketFlags, out SocketError errorCode); } 

使用它们的类有2个构造函数。 一个注入一个ISocket用于测试,然后一个注入应用程序使用它自己的Socket。

 public class HTTPRequestFactory3 { internal ISocket _socket; ///  /// Creates a socket and sends/receives information. Used for mocking to inject ISocket ///  internal HTTPRequestFactory3(ISocket TheSocket) { _socket = TheSocket as ISocket; this.Setup(); } ///  /// Self Injects a new Socket. ///  public HTTPRequestFactory3() { SocketWrapper theSocket = new SocketWrapper(); _socket = theSocket as ISocket; this.Setup(); } } 

然后你的测试可以创建一个ISocket,设置期望并validation它们运行所有相同的代码,上面的类将使用真正的套接字。 此测试validation该部分代码。

  [Test] public void NewSocketFactoryCreatesSocketDefaultConstructor() { webRequestFactory = new HTTPRequestFactory3(); Assert.NotNull(webRequestFactory._socket); Socket testSocket = webRequestFactory._socket as Socket; Assert.IsInstanceOf(testSocket); } 

您最好在测试中创建一个接口并对其进行模拟,并在代码中实现一个包装类,将所有方法调用转发给.NET套接字,如thinkzig所述。 看看这个链接,同样的问题: 如何在C#中模拟文件系统进行unit testing?