Как люди могут издеваться над TcpClient (или такими вещами, как TcpClient)?TDD и издевательство TcpClient
У меня есть служба, которая принимает TcpClient. Должен ли я обернуть это чем-то еще более насмешливым? Как мне подойти к этому?
Как люди могут издеваться над TcpClient (или такими вещами, как TcpClient)?TDD и издевательство 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();
}
}
Использование шаблона адаптера является, безусловно, стандартным подходом TDD к проблеме. Тем не менее, вы могли бы просто создать другой конец TCP-соединения и иметь свой тестовый жгут.
IMO широко распространенное использование адаптивного класса обфускации наиболее важных частей конструкции, а также имеет тенденцию удалять многие вещи из тестирования, которые действительно должны быть протестированы в контексте. Таким образом, альтернатива заключается в создании ваших тестовых лесов для включения большей части тестируемой системы. Если вы строите свои тесты с нуля, вы все равно сможете определить причину сбоя данного класса или функции, он просто не будет изолирован ...
Я думаю @ 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 связанных деталей в целом (если это дизайн цель), и вы можете даже трубы в тестовом входе с жестким кодированным набором значений , или тестовый входной файл. Очень хорошо, если вы находитесь на пути к тестированию своего кода надолго.
Это замечательно! Благодаря! – 2008-09-29 20:49:31
+1 лучшее объяснение плюс хороший простой пример – Ahmad 2010-10-11 07:22:26