Страницы

Поиск по вопросам

четверг, 11 октября 2018 г.

Как тестировать методы которые не возвращают значения?

Предположим у меня есть следующий класс
public class Residue { public int Id {get;set;} public int WarehouseId {get;set;} public int MaterialAssetId {get;set;}
public virtual ICollection Histories {get;set;}
public Residue() { this.Histories = new List(); } }
Мне необходимо добавить метод который будет пересчитывать остатки с даты переданной в качестве параметра.
В тело класса добавляю новый метод
public void RecalculateResidueSince(DateTime since) { throw new NotImplementedException(); }
Первый же тест который я решил реализовать это выход из метода если свойство Histories пустое;
Добавил в решение новый проект UnitTest:
[TestClass] public class TestOfResidueMethods { [TestMethod] public void Test_RecalculateResidueForEmptyHistory() { var residue = new Residue(); residue.RecalculateResidueSince(DateTime.Now); } }
и тут у меня ступор а что делать дальше в тестовом методе, если бы это была функция то тогда я бы сверил то что получилось в результате с тем что ожидаю.
Подскажите как тестировать и надо ли писать такие тесты для таких методов?
UPD:
после написания этого метода я видоизменил тестируемый метод следующим образом:
public void RecalculateResidueSince(DateTime since) { if(!this.Histories.Any()) return; }
т.е. если фактически остатков нет то соответственно ничего не делать, но не соображу как проверить это в тесте


Ответ

В тестах тестируются не возвращаемые значения и не реализация методов, а контракт. Контракт -- это некоторые обещания метода о том, что он сделает. Т.е. своеобразный набор пар "вход-выход". Если метод при этом принимает параметры, то количество этих обещаний (пар) может увеличиться и будет зависеть от комбинаций значений параметров.
При этом "выход" может быть разный:
в виде возвращаемого значения функции в виде изменения состояния текущего объекта или других объектов, а также вызова методов в других объектах (зависимостях)
С первым типом контракта все понятно. Получил значение, проверил его.
Во втором типе контракт нужно проверять изменения состояния текущего объекта, а также, если у вас есть зависимости и в тестах вы их мокаете, обращения к этим зависимостям.

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

Комментариев нет:

Отправить комментарий