Добрый день. Вопрос по unit тестам.
Имеется asp.net mvc приложение, где бизнес логика реализована в виде классов менеджеров, которые в свою очередь тянут данные из классов репозиториев.
Репезитории в менеджере инициализируются с помощью инъекции ioc unity через интерфейсы в конструкторе.
Вопрос в том, как правильно тестировать методы менеджера.
На данный момент, для тестирования какого либо метода менеджера, требуется сначало mock-нуть репозитории, создать менеджер с этими фейковыми репозиториями, подменить вызовы методов репозиториев, которые используются в тестируемом методе менеджера, подменить методы менеджера вызываемые в тестируемом методе.
Т.е получается для того что бы написать тест, нужно знать как написан тестируемый метод, т.е по сути тестируется не результат выполнения, а его код.
Мне кажется что этот подход полностью не верно, и тестировать метод нужно по стратегии черного ящика? Подскажите как правильно писать тесты в таких случаях.
спасибо
Писать модульные или интеграционные тесты -- дело вкуса, тем более, что четкой границы между ними нет -- ведь функциональность одного "юнита" может со временем "расползтись" по разным. И таки да, если уж Вы используете моки, то Вы, в каком-то смысле, тестируете не фичи, а способ их реализации. Частично с этим позволяет бороться мок-контейнер. А так -- дело вкуса. Я лично предпочитаю обходиться без репозиториев вообще, а в случае сложных запросов использовать Specification Objects -- тогда тестировать можно как с помощью тестовой базы, так и используя вручную изготовленный IQuerable.
Вот только подменять вызовы методов самого менеджера я бы не стал. Если Вам так хочется это сделать, может, стоит отправить их в другой класс, или сделать private?
Здравствуйте, Аноним, Вы писали:
А>Добрый день. Вопрос по unit тестам. А>Имеется asp.net mvc приложение, где бизнес логика реализована в виде классов менеджеров, которые в свою очередь тянут данные из классов репозиториев. А>Репезитории в менеджере инициализируются с помощью инъекции ioc unity через интерфейсы в конструкторе. А>Вопрос в том, как правильно тестировать методы менеджера. А>На данный момент, для тестирования какого либо метода менеджера, требуется сначало mock-нуть репозитории, создать менеджер с этими фейковыми репозиториями, подменить вызовы методов репозиториев, которые используются в тестируемом методе менеджера, подменить методы менеджера вызываемые в тестируемом методе. А>Т.е получается для того что бы написать тест, нужно знать как написан тестируемый метод, т.е по сути тестируется не результат выполнения, а его код. А>Мне кажется что этот подход полностью не верно, и тестировать метод нужно по стратегии черного ящика? Подскажите как правильно писать тесты в таких случаях. А>спасибо
А>Т.е получается для того что бы написать тест, нужно знать как написан тестируемый метод, т.е по сути тестируется не результат выполнения, а его код.
Что такое результат выполнения? Преобразованные данные? Судя по описанию, у тебя все же что-то внешне напоминающее ООП, поэтому результат выполнения — это взаимодействие объекта с другими объектами. И это — не детали имплементации, это суть. Каково поведение твоего "менеджера" (это не название, это утверждение: "я не знаю, как назвать этот класс")? Запросить данные из репозиториев (название не лучше) и послать сообщение какому-то другому объекту. В этом сценарии главное, что тестируется — то, что изменяет мир вокруг объекта, и это явно не получение данных из репозиториев, это — то самое сообщение другому объекту. Поэтому репозитории должны быть не замочены, а застаблены (факт вызова/не вызова стаба не влияет на результат теста) — мы предоставляем данные, а получать ли их — дело объекта. Кроме того, это делает тест менее хрупким.
С другой стороны, если функция твоего кода — преобразование данных, то и реализуй это явно в парадигме ФП: репозитории — это генераторы данных, менеджеры — просто чистые функции. И тестирование будет простым, как дверь.