хранение данных модульного тестирования - PullRequest
6 голосов
/ 29 марта 2009

Предположим, у меня есть интерфейс с методами storeData (ключ, данные) и getData (ключ). Как мне проверить конкретную реализацию? Должен ли я проверить, правильно ли были установлены данные на носителе данных (например, в базе данных sql), или я должен просто проверить, возвращает ли он правильные данные с помощью getData?

Если я просматриваю данные в базе данных, мне кажется, что я также тестирую внутренние компоненты метода, но только проверяю, дает ли он те же данные обратно, чувствую себя неполным.

Ответы [ 5 ]

2 голосов
/ 29 марта 2009

Что вы хотите сделать в модульном тесте, это убедиться, что метод выполняет ту работу, которую он должен делать. Если метод использует зависимости для выполнения своей работы, вы должны смоделировать эти зависимости и убедиться, что ваш метод вызывает методы для объектов, от которых он зависит, с соответствующими аргументами. Таким образом, вы тестируете свой код изолированно.

Одним из преимуществ этого является то, что он будет направлять дизайн вашего кода в лучшем направлении. Например, чтобы использовать макетирование, вы естественным образом стремитесь к более разъединенному коду, используя внедрение зависимостей. Это дает вам возможность легко заменить ваши фиктивные объекты фактическими объектами, от которых зависит ваш класс. Вы также заканчиваете тем, что внедрили интерфейсы, которые более естественны для насмешки. Обе эти вещи являются хорошими шаблонами проектирования и улучшат ваш код.

Например, чтобы протестировать ваш конкретный пример, ваш класс может зависеть от фабрики создания соединений с базой данных и сборщика для создания параметризованных команд SQL, которые выполняются через соединение. Вы передадите эти смоделированные версии этих объектов своему классу и убедитесь, что были вызваны правильные методы для установки соединения и команды, построения правильной команды, ее выполнения и разрыва соединения. Или, возможно, вы вводите уже открытое соединение и просто создаете команду и вызываете ее. Дело в том, что ваш класс построен на основе интерфейса или набора интерфейсов, и вы используете mocking для предоставления объектов, которые реализуют эти интерфейсы и могут записывать вызовы и предоставлять правильные возвращаемые значения методам, которые вы ожидаете использовать из интерфейса (ов).

2 голосов
/ 29 марта 2009

Вы, похоже, оказались втянутыми в шумиху модульного тестирования, то, что вы будете делать, на самом деле является интеграционным тестом. Установка и возврат одного и того же значения с одного и того же ключа - это модульное тестирование, которое вы выполняли бы с фиктивной реализацией механизма хранения, но фактически проверяли реальное хранилище, скажем, ваша база данных, как и вы, больше не является модульным тестом. , но это фундаментальная часть тестирования, и для меня это звучит как интеграционное тестирование. Не используйте модульное тестирование в качестве молотка , выбирайте правильные инструменты для правильной работы. Разделите тестирование на несколько слоев.

1 голос
/ 29 марта 2009

В подобных случаях я обычно создаю методы SetUp и TearDown, которые запускаются до / после моих модульных тестов. Эти методы настроят все необходимые мне тестовые данные в БД и удалят все тестовые данные, когда я закончу. Пример псевдокода:

Const KEY1 = "somekey"
Const VALUE1= "somevalue"


Const KEY2 = "somekey2"
Const VALUE2= "somevalue2"



Sub SetUpUnitTests()
{
   Insert Into SQLTable(KEY1,VALUE1)
}


//this test is not dependent on the setData Method
Sub GetDataTest()
{
   Assert.IsEqual(getData(KEY1),VALUE1)
}

//this test is not dependent on getData Method
Sub SetDataTest()
{
   storeData(newKey,NewData)
   Assert.IsNotNull(Direct Call to SQL [Select data from table where key=KEY2]) 

}

Sub TearDownUnitTests()
{
   Delete From table Where key in (KEY1, KEY2)
} 
0 голосов
/ 29 марта 2009

Тестирование на концертах - обычная техника (по крайней мере, по моему опыту), и я бы не стал уклоняться от нее. Я использовал этот же шаблон для сериализации / десериализации, анализа и печати. ​​

Если вы не хотите использовать базу данных, вы можете использовать макет базы данных. Некоторые люди испытывают те же чувства, что и вы, когда используете макеты - это отчасти зависит от конкретной реализации. Как и во всем, это компромисс: рассмотрите преимущества насмешек (быстрее, не зависит от дб) по сравнению с его недостатками (не обнаружит реальных проблем с дб, медленнее).

0 голосов
/ 29 марта 2009

Я думаю, что это зависит от того, что случится с данными позже - если вы когда-либо собираетесь получить доступ к данным, используя storeData и getData, почему бы не протестировать методы совместно? Я предполагаю, что есть шанс, что ошибка возникнет, и будет немного сложнее выяснить, находится ли она в storeData или getData, но я бы посчитал это приемлемым риском, если он

  1. упрощает выполнение теста, а
  2. скрывает внутренние органы, как вы говорите

Если данные будут считаны из базы данных или вставлены в нее с использованием какого-либо другого механизма, я бы проверил базу данных с использованием SQL, как вы предлагаете.

@ brendan делает хорошее замечание - какой бы метод вы ни выбрали, вы будете вставлять данные в базу данных. Хорошей идеей будет очистить данные до и после испытаний, чтобы убедиться, что вы можете достичь последовательных результатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...