Страницы

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

среда, 4 декабря 2019 г.

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

#c_sharp #юнит_тесты


Предположим у меня есть следующий класс

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;
}


т.е. если фактически остатков нет то соответственно ничего не делать, но  не соображу
как проверить это в тесте
    


Ответы

Ответ 1



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

Ответ 2



Тут можно проверять две вещи: ожидаемое состояние (своего класса или параметра (мокабельно), который внутрь передается) выбрасываемые исключения (только негативный сценарий)

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

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