简体   繁体   English

对具有由工厂方法创建的多个依赖项实例的类进行单元测试?

[英]Unit test a class that has multiple dependencies instances created by factory method?

Consider the following situation:考虑以下情况:

NOTE: Code below is only for asking the question about unit tests.注意:下面的代码仅用于询问有关单元测试的问题。 Please ignore how threads are (not) handled and other problems with the code that are not question related.请忽略线程是如何(不)处理的以及与问题无关的代码的其他问题。

I have a class that listens for a TCP connection on 2 different ports: 1234 and 5678 (could be more.. I'm using two just to keep the example small).我有一个类在 2 个不同的端口上侦听 TCP 连接:1234 和 5678(可能更多......我使用两个只是为了保持示例小)。 This is done by using 2 sockets created with an abstract factory.这是通过使用由抽象工厂创建的 2 个套接字来完成的。
As soon as a client connects to one of the two ports, the class will save the socket for that TCP connection and invoke an event indicating to which port a client has connected.一旦客户端连接到这两个端口之一,该类就会保存该 TCP 连接的套接字并调用一个事件来指示客户端已连接到哪个端口。
The user of this class will then be able to send data using that connection.此类的用户随后将能够使用该连接发送数据。

public class ClassToTest
{
    private readonly ISocketFactory _socketFactory;

    private ISocket _connectedSocket;

    public event EventHandler<int> Connected;

    public ClassToTest(ISocketFactory socketFactory)
    {
        _socketFactory = socketFactory;
    }

    public void Listen(IPAddress ipAddress)
    {
        var listener1234 = _socketFactory.CreateTcp();
        listener1234.Bind(new IPEndPoint(ipAddress, 1234));
        listener1234.Listen(1);

        var listener5678 = _socketFactory.CreateTcp();
        listener5678.Bind(new IPEndPoint(ipAddress, 5678));
        listener5678.Listen(1);

        var thread1 = new Thread(() => 
        {
            _connectedSocket = listener1234.Accept();
            Connected?.Invoke(this, 1234);
        });

        var thread2 = new Thread(() => 
        {
            _connectedSocket = listener5678.Accept();
            Connected?.Invoke(this, 5678);
        });
    }

    public void Send(byte[] data)
    {
        _connectedSocket?.Send(data);
    }

}

Now let's say that in the unit test for this class, I inject a MockSocketFactory implementation that will return MockSockets.现在假设在此类的单元测试中,我注入了一个将返回 MockSockets 的 MockSocketFactory 实现。 This way I can mock the behaviour of the sockets without relaying on real IO.这样我就可以模拟套接字的行为,而无需中继真实的 IO。

My question is: How can I distinguish in the unit test setup which of the MockSocket returned by the MockSocketFactory will be used for port 1234 and for port 5678?我的问题是:如何在单元测试设置中区分 MockSocketFactory 返回的哪个 MockSocket 将用于端口 1234 和端口 5678? This without relaying on the order of calls to SocketFactory.CreateTcp() in the tested class implementation.这不依赖于在测试的类实现中调用 SocketFactory.CreateTcp() 的顺序。

My idea is for example to be able to mock that the socket that is listening on port 1234 accepts a connection.例如,我的想法是能够模拟正在侦听端口 1234 的套接字接受连接。

If you don't want to rely on the ordering of calls you should modify or overload your CreateTcp() method to take an IPEndPoint .如果您不想依赖调用顺序,您应该修改或重载您的CreateTcp()方法以获取IPEndPoint Within the IPEndPoint , you specify the target point.IPEndPoint中,您指定目标点。 This way you will determine which MockSocket is used to listen on which port.这样您将确定使用哪个MockSocket来侦听哪个端口。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM