人々は TcpClient (または TcpClient のようなもの) をモックアウトするためにどのようにアプローチしますか?
TcpClient を受け取るサービスがあります。それをもっとモック可能な何かでラップする必要がありますか?これにどのようにアプローチすればよいですか?
人々は TcpClient (または TcpClient のようなもの) をモックアウトするためにどのようにアプローチしますか?
TcpClient を受け取るサービスがあります。それをもっとモック可能な何かでラップする必要がありますか?これにどのようにアプローチすればよいですか?
テストに適していないクラス (つまり、シールされている/インターフェイスを実装していない/メソッドが仮想ではない) をモックする場合は、おそらくAdapterデザイン パターンを使用することをお勧めします。
このパターンでは、インターフェイスを実装するラッピング クラスを追加します。次に、インターフェイスをモックし、すべてのコードで、使いにくい具象クラスではなく、そのインターフェイスを使用するようにします。次のようになります。
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();
}
}
@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関連の詳細から完全に切り離され(それが設計目標である場合)、ハードコードされた値のセットまたはテスト入力ファイルからテスト入力をパイプすることもできます。長期にわたってコードをテストするための道を進んでいる場合は、非常に手がかりです。
Adapter パターンを使用することは、問題に対する標準的な TDD アプローチであることは間違いありません。ただし、TCP 接続のもう一方の端を作成し、テスト ハーネスでそれを駆動することもできます。
IMO アダプター クラスの広範な使用は、設計の最も重要な部分を難読化し、また、コンテキストで実際にテストする必要があるテストから多くのものを削除する傾向があります。そのため、別の方法は、テスト対象のシステムをより多く含めるためにテストの足場を構築することです。テストをゼロから構築している場合でも、失敗の原因を特定のクラスまたは関数に分離する機能を実現できますが、分離することはできません...