verifiable setup mock examples dotnet c# networking tdd mocking

c# - setup - TDD y burlarse de TcpClient



setup mock (3)

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

No me burlaría del TcpClient directamente, porque eso aún te ataría demasiado a la implementación subyacente aunque hayas escrito pruebas. Es decir, su implementación está vinculada a un método TcpClient específicamente. Personalmente, probarí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 desvinculará por completo de los detalles relacionados con Tcp (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ás en camino a probar tu código a largo plazo.

¿Cómo se acercan las personas burlándose de TcpClient (o cosas como TcpClient)?

Tengo un servicio que admite un TcpClient. ¿Debería envolver eso en algo más más burlable? ¿Cómo debería abordar esto?


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

IMO 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 andamio de prueba para incluir más del sistema bajo prueba. Si estás construyendo tus pruebas desde el principio, aún lograrás la capacidad de aislar la causa de una falla en una clase o función determinada, simplemente no será aislada ...


Al llegar a las clases de prueba que no son amigables para las pruebas (es decir, si se sella / no se implementa ninguna interfaz / los métodos no son virtuales), es probable que desee utilizar el patrón de diseño del adaptador .

En este patrón, agrega una clase de ajuste que implementa una interfaz. Debería burlarse de la interfaz y asegurarse de que todo su código utiliza esa interfaz en lugar de la clase concreta antipática. Se vería algo como esto:

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