Pregunta

¿Cómo se acerca la gente burlándose de TcpClient (o cosas como TcpClient)?

Tengo un servicio que acepta un TcpClient. ¿Debo envolver eso en algo más burlón? ¿Cómo debería abordar esto?

¿Fue útil?

Solución

Al venir a simulacros de clases que no son fáciles de probar (es decir, selladas / no implementando ninguna interfaz / los métodos no son virtuales), es probable que desee utilizar Patrón de diseño del adaptador .

En este patrón, agrega una clase de ajuste que implementa una interfaz. A continuación, debe burlarse de la interfaz y asegurarse de que todo su código use esa interfaz en lugar de la clase concreta hostil. Se vería así:

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();
   }
}

Otros consejos

Creo que @Hitchhiker está en el camino correcto, pero también me gusta pensar en abstraer cosas como esas un paso más allá.

No me burlaría del TcpClient directamente, porque eso aún lo vincularía demasiado a la implementación subyacente a pesar de que haya escrito pruebas. Es decir, su implementación está vinculada a un método TcpClient específicamente. Personalmente, intentaría algo como esto:

   [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();
    }

Esta implementación lo desacoplará de los detalles relacionados con Tcp por completo (si ese es un objetivo de diseño), e incluso puede canalizar la entrada de prueba desde un conjunto de valores codificados o un archivo de entrada de prueba. Muy útil si está en camino de probar su código a largo plazo.

El uso del patrón Adaptador es definitivamente el enfoque TDD estándar para el problema. Sin embargo, también puede crear el otro extremo de la conexión TCP y hacer que su arnés de prueba lo controle.

En mi opinión, el uso generalizado de la clase de adaptador ofusca las partes más importantes de un diseño y también tiende a eliminar muchas cosas de la prueba que realmente deberían probarse en contexto. Entonces, la alternativa es construir su andamiaje de prueba para incluir más del sistema bajo prueba. Si está construyendo sus pruebas desde cero, seguirá logrando la capacidad de aislar la causa de una falla en una clase o función determinada, simplemente no estará aislada ...

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top