Мы пытаемся использовать TDD для создания нашей системы, и мы пришли к ситуации, когда мы не можем понять, что такое правильный курс TDD.TDD - Как протестировать .Read() без .Write()?
Мы спрятали файл IO за интерфейсом, как так:
public interface IFileIo
{
byte[] Read(string fileName);
void Write(string filename, byte[] data);
}
и в настоящее время мы создаем InMemoryFileIo
, что мы можем использовать вместо реального SystemFileIo
класса, который мы будем использовать для производства ,
Мы хотим убедиться, что этот InMemoryFileIo
работает правильно, и могут быть случаи, когда мы хотим использовать его вместо фактической файловой системы, поэтому это должно быть «качество продукции».
Вопрос в том, что делает все «правильный путь TDD», как мы можем создать тест для .Read()
или .Write()
, где они не зависят друг от друга?
Для того, чтобы проверить, что .Read()
работали правильно, мы нуждались бы успешно сделал вызов .Write()
первой, а так же, чтобы проверить, что .Write()
работает правильно, мы тогда должны были бы назвать .Read()
впоследствии. Делая это, мы фактически создали один и тот же тест дважды (устраиваем, затем записываем, затем читаем, а затем утверждаем).
Допустим, у нас есть два теста, один из которых проверяет .Read()
и тот, который проверяет .Write()
. Если какая-либо из этих функций не работает, то оба теста терпят неудачу. Это нарушает принцип, согласно которому «Тест должен иметь только одну причину неудачи».
Пример здесь для файла IO, но этот же вопрос возник из-за нас при работе с базой данных (тест put
без get
).
В этом случае это хорошо, просто проверьте их вместе - сбой на одном будет означать, что другой тоже не работает слишком сильно, и сообщение об ошибке в тесте скажет вам, какой из них был неудачен в любом случае в случаях, которые вы можете узнать.Не переусердствуйте и не испытывайте соблазна использовать какие-то ложные отражения, которые лежат - он находится в одной и той же единице здесь, и это имеет смысл. –
«Правильный» способ (который опять же, не беспокойтесь об этом) был бы для InMemoryFileIo взять 'byte []' в своем конструкторе вместо его создания (инъекция зависимостей), которая позволит вам предварительно установить данные чтобы читать или запускать проверки данных, написанных внешне друг с другом - действительно, не переусердствуйте, просто напишите те тесты, которые имеют для вас смысл, и четко определите недостатки системы. –
Я думаю, что стоит отметить, что если ваш IO-класс в памяти используется только как двойной тест, он должен быть достаточно простым, чтобы не требовать кучу тестирования. точка имеет подделку для других классов, которые вы TDDing, которые зависят от интерфейса правильно? связать их прохождение или не пройти тест на то, является ли ваш фальшивый файл IO в памяти ошибкой без ошибок, кажется мне потенциально плохим идеей. Я предлагаю держать ваши заглушки мертвыми просто. – kai