#c_sharp #юнит_тесты
Предположим у меня есть следующий класс public class Residue { public int Id {get;set;} public int WarehouseId {get;set;} public int MaterialAssetId {get;set;} public virtual ICollectionHistories {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; } т.е. если фактически остатков нет то соответственно ничего не делать, но не соображу как проверить это в тесте
Ответы
Ответ 1
В тестах тестируются не возвращаемые значения и не реализация методов, а контракт. Контракт -- это некоторые обещания метода о том, что он сделает. Т.е. своеобразный набор пар "вход-выход". Если метод при этом принимает параметры, то количество этих обещаний (пар) может увеличиться и будет зависеть от комбинаций значений параметров. При этом "выход" может быть разный: в виде возвращаемого значения функции в виде изменения состояния текущего объекта или других объектов, а также вызова методов в других объектах (зависимостях) С первым типом контракта все понятно. Получил значение, проверил его. Во втором типе контракт нужно проверять изменения состояния текущего объекта, а также, если у вас есть зависимости и в тестах вы их мокаете, обращения к этим зависимостям. Контракт вашего метода заключается в следующем (из того, что вы описали в вопросе): он пересчитывает остатки, начиная с переданной ему даты, при этом более ранние остатки не изменяются если остатков нет, он ничего не делает Соответственно ваши тесткейсы должны быть следующие: Пустая коллекция остатков. Вызвать метод и проверить, что состояние остатков не изменилось. Как более жесткий вариант: проверить, что состояние всего объекта не изменилось/не было обращений к зависмостям. (Но это уже на грани и попахивает паранойей, хотя в каких-то случаях может быть и оправдано.) Непустая коллекция остатков за разные даты. Вызвать метод за дату, которая больше максимальной даты в остатках. Проверить, что состояние остатков/всего объекта не изменилось. Непустая коллекция остатков. Вызвать метод за дату, которая больше минимальной, но меньше максимальной даты в остатках. Проверить, что остатки с меньшей датой не изменились и что остатки с большей датой изменились корректно.Ответ 2
Тут можно проверять две вещи: ожидаемое состояние (своего класса или параметра (мокабельно), который внутрь передается) выбрасываемые исключения (только негативный сценарий)
Комментариев нет:
Отправить комментарий