Тестирование классов с потоками, событиями и закрытыми методами - PullRequest
3 голосов
/ 27 октября 2010

общий консенсус

Я достаточно много читал по теме тестирования сложных классов и частных методов.

Общий консенсус выглядит так:

  • "если вам нужно протестировать закрытые методы, значит ваш класс плохо спроектирован"
  • "если ваш класс сложный, то вам нужно выделить его"

Итак, мне нужна ваша помощь.

Класс задачи

Итак, у меня есть относительно простой класс, у которого длительное выполнение задание:

  • опрос источника данных
  • сделать очень простое сопоставление данных
  • отправить эти данные куда-то еще

Дополнительно:

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

проблема тестирования

Цель класса - абстрагироватьсямного отказоустойчивости и многопоточности ... в основном с помощью простого класса таймера и некоторых внутреннихпозволяет отслеживать ошибки и т. д.

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

Как следуетЯ тестирую этот класс ... особенно потому, что так много методов являются закрытыми?

ура, ребята

Ответы [ 2 ]

4 голосов
/ 27 октября 2010

Я бы извлек код для опроса данных в отдельный класс, который можно смоделировать, а также извлек бы код, который отправляет эти данные по той же причине. Возможно, вы захотите извлечь код отображения данных, в зависимости от того, насколько он тривиален.

Я бы определенно использовал фиктивные таймеры в модульных тестах, в противном случае ваши тесты сложно настраивать и запускать медленно. Вы можете либо передать таймер в конструкторе, либо предоставить свойство, которое вы можете установить. Я часто создаю обычный таймер в конструкторе, а затем перезаписываю его из моего модульного теста.

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

Если у вас действительно есть многопоточные сценарии, которые вам нужно протестировать, есть некоторые инструменты для координации потоков из теста. Одним из них является порт, который я создал из Java MultithreadedTC , который называется TickingTest .

1 голос
/ 27 октября 2010

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

РЕДАКТИРОВАТЬ: Упс! Не видел тег C #. Может быть, есть C # эквивалент JMock.

...