有人成功模拟了.NET 中的 Socket 类吗?
我正在尝试在 C# 中模拟 System.net.Sockets.Socket 类 - 我尝试使用 NUnit 模拟,但它无法模拟具体类。 我也尝试使用 Rhino Mocks,但它似乎使用了该类的真实版本,因为它在调用 Send(byte[]) 时抛出了 SocketException。 有人使用任何模拟框架成功创建并使用了 Socket 模拟吗?
I'm trying to mock out the System.net.Sockets.Socket class in C# - I tried using NUnit mocks but it can't mock concrete classes. I also tried using Rhino Mocks but it seemed to use a real version of the class because it threw a SocketException when Send(byte[]) was called. Has anyone successfully created and used a Socket mock using any mocking framework?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
上面的类仅模拟您的发送方法。 这实际上模拟了一个 Socket。 它继承了Socket的全部,然后实现了ISocket接口。 ISocket 需要实现您需要模拟的任何 Socket 方法或属性的签名
该接口看起来像这样,但有两个方法被拒绝:
使用它们的类有 2 个构造函数。 一种注入 ISocket 进行测试,然后注入一个 ISocket 来供应用程序使用。
然后,您的测试可以创建一个 ISocket,设置期望并验证它们运行上述类将与真实套接字一起使用的所有相同代码。 此测试验证该部分代码。
The above class only Mocks your Send Method. This actually mocks a Socket. It Inherits all of Socket and then Implements the ISocket interface. ISocket needs to implement the signatures of any Socket methods or properties you need to mock
The interface looks like this with two methods declined:
The Class that uses them has 2 constructors. One injects an ISocket for testing and then one that makes it's own Socket that the application uses.
Then your tests can create a ISocket, set up expectations and verify them running all the same code the above class will use with a real socket. This test validates that section code.
每当我在 Moq 上遇到此类问题时,我最终都会创建一个接口来抽象出我无法模拟的东西。
因此,在您的实例中,您可能有一个实现 Send 方法的 ISocket 接口。 然后让你的模拟框架来模拟它。
在您的实际代码中,您会有一个像这样的类
不确定是否满足您的需求,但它是一个选项。
Whenever I run into these kinds of problems with Moq I end up creating an interface to abstract away the thing I can't mock.
So in your instance you might have an ISocket interface that implements the Send method. Then have your mocking framework mock that instead.
In your actual code, you'd have a class like this
Not sure if that meets your needs, but it's an option.
调用 Send 方法时收到 SocketException 的原因是 Send 不是可重写的方法。 为了让 RhinoMocks 能够模拟属性或方法的行为,它必须在接口中定义(然后我们创建模拟)或者是可重写的。
对此的唯一解决方案是创建一个可模拟的包装类(如 thinkzig 建议的那样)。
The reason you get a SocketException when you call the Send method is because Send is not an overridable method. For RhinoMocks to be able to mock the behavior of a property or method, it has to either be defined in an interface (which we then create our mock off) or is overridable.
Your only solution to this is to create a mockable wrapper class (as suggested by thinkzig).
我使用 thinkzig 建议的方法(Socket 的适配器类)创建了一个示例控制台应用程序。 它使用 RhinoMocks 和 NUnit。 您可以在这里下载: 如何模拟 System.Net.Sockets.Socket。
I've created an example console application using the method thinkzig suggests (an adapter class for Socket). It uses RhinoMocks and NUnit. You can download it here: How to mock System.Net.Sockets.Socket.
您最好创建一个接口并在测试中模拟它,并在代码中实现一个包装类,将所有方法调用转发到 .NET 套接字,如 thinkzig 所说。 看看这个链接,它是同样的问题: 如何在 C# 中模拟文件系统以进行单元测试?
You'd better to create an interface and mock it in your test, and implement a wrapper class in your code, that forward all method calls to .NET socket as thinkzig said. Look at this link, it's same issue: How do you mock out the file system in C# for unit testing?