TDD和惩戒出来的TcpClient(TDD and Mocking out TcpClient)

2019-07-20 10:06发布

人们怎样的方式嘲弄了的TcpClient(或之类的东西的TcpClient)?

我有一个发生在一个TcpClient的服务。 我应该换在别的更mockable的东西吗? 我应该如何看待呢?

Answer 1:

当来到模拟类未测试友好(即密封/未实现任何接口/方法不是虚拟的),你可能会想使用的适配器的设计模式。

在这个模式中添加实现接口的包装类。 然后,您应该嘲笑接口,并确保所有代码使用这个接口,而不是不友好的具体类。 这将是这个样子:

public interface ITcpClient
{
   Stream GetStream(); 
   // Anything you need here       
}
public class TcpClientAdapter: ITcpClient
{
   private TcpClient wrappedClient;
   public TcpClientAdapter(TcpClient client)
   {
    wrappedClient = client;
   }

   public Stream GetStream()
   {
     return wrappedClient.GetStream();
   }
}


Answer 2:

我认为@Hitchhiker是在正确的轨道上,但是我也喜欢思考抽象出这样的事情只是进了一步。

我不会直接模拟出了TcpClient的,因为这将仍然配合你很近的地方,即使你写测试的底层实现。 也就是说,您的实现依赖于一个TcpClient的方法具体。 就个人而言,我会尝试这样的事:

   [Test]
    public void TestInput(){

       NetworkInputSource mockInput = mocks.CreateMock<NetworkInputSource>();
       Consumer c = new Consumer(mockInput);

       c.ReadAll();
    //   c.Read();
    //   c.ReadLine();

    }

    public class TcpClientAdapter : NetworkInputSource
    {
       private TcpClient _client;
       public string ReadAll()
       { 
           return new StreamReader(_tcpClient.GetStream()).ReadToEnd();
       }

       public string Read() { ... }
       public string ReadLine() { ... }
    }

    public interface NetworkInputSource
    {
       public string ReadAll(); 
       public string Read();
       public string ReadLine();
    }

此实现将分离你的Tcp相关的细节完全(如果这是一个设计目标),你甚至可以在测试输入管道从一个硬编码值的集合,或测试输入文件。 很有一手,如果你在路上,以测试你的代码的长途上。



Answer 3:

使用适配器模式是最肯定的标准TDD解决问题的方法。 你可以,但是,也只是建立TCP连接的另一端,有你的测试工具驱动该。

IMO的广泛使用适配器类的模糊化设计的最重要的部分,而且还趋向于从被测试真的应该在上下文中进行测试去掉了很多东西。 因此,另一种方法是建立你的测试支架,包括更多的系统测试。 如果你是从头开始建立你的测试,你还是会达到一个失败的原因隔离到一个给定的类或函数的能力,它只是不会是孤立...



文章来源: TDD and Mocking out TcpClient