Полный гайд по тестированию на Flutter. Часть 6: Тестовые двойники: Faking vs Mocking
Hola, Amigos! На связи Павел Гершевич, Mobile Team Lead агентства продуктовой разработки Amiga. Мы с вами разобрали уже больше половины гайда о тестировании в Flutter! Сегодня статья перевод посвящена технике Faking. А в следующих частях рассмотрим часто встречаемые ошибки и лучшие практики в написании Unit-тестов. Так что не переключайтесь!
Новые выпуски, полезные плагины и библиотеки, кейсы и личный опыт в нашем авторском телеграм-канале Flutter. Много. В нашем сообществе уже 2645 мобильных разработчиков, присоединяйтесь!
Faking
Что произойдет в примере из прошлой статьи, если добавить параметр с типом BuildContext в функцию push?
Тогда, нужно обновить тест таким образом:
Но BuildContext — абстрактный класс, тогда как можно его инициализировать?
На этом этапе необходимо создать новый фейковый тип, расширив класс Fake.
Вместо создания реального объекта BuildContext(), нужно создать только фейковый объект FakeBuildContext().
Однако, если наследоваться от класса Mock вместо Fake, то тест все равно пройдет. Так в чем же разница между Fake и Mock?
Faking vs Mocking
Термины Fake и Mock называют «Тестовыми двойниками». Тестовые двойники — объекты, которые заменяют реальные во время тестирования. Другими словами, обе техники используются для создания фейковых классов и объектов. Также они применяются для имитации методов фейковых объектов и для контроля возвращаемых значений этими методами.
Если техника Mocking использует Stubbing для имитации и контроля результата функций, то с Faking её применять нельзя. Faking позволяет переопределять методы реального класса в нужном для тестирования виде.
Давайте снова напишем тесты для класса LoginViewModel из части 3, но будем использовать технику Faking вместо Mocking.
Сначала создадим класс FakeSharedPreferences, который наследуется от Fake. Если использовать Mock, то необходимо подменить методы getString и clear, но при использовании Faking их нужно переопределить.
Далее, нам нужно будет убрать строки кода, которые используют Stubbing.
Однако, при запуске теста, он упадет.
Это произошло из-за переопределения функции clear для возвращения Future.value(true), но ожидается, что вернется Future.value(false). Поэтому не нужно использовать класс FakeSharedPreferences для проверки этого тест кейса. Вместо этого создадим новый класс, чтобы переопределить функцию clear, чтобы она возвращала Future.value(false).
Тогда для падающего теста, показанного выше, будем использовать класс SecondFakeSharedPreferences.
Можно заметить, когда используется Faking, можно создать несколько классов Fake, чтобы достичь этого. Это недостаток использования Faking. А какие есть плюсы у Faking?
Чтобы узнать преимущества Faking, давайте перейдем к другому примеру. Допустим, есть классы JobViewModel, JobRepository и JobData:
Это класс JobViewModel.
Теперь напишем тест для него.
Сначала необходимо создать класс FakeJobRepository. Создадим переменную jobDataInDb с типом List для имитации реальных данных в базе данных Isar. Тогда можно переопределить все 4 метода в JobRepository.
Далее протестируем функцию addJob в классе JobViewModel.
Больше тест кейсов можно найти здесь.
Таким образом, проверку прошли не только отдельные функции по типу getAllJobs и addJob, но и тест кейсы, где эти функции работают вместе. Это помогает сделать тестирование более похожим на запуск в реальном окружении.
Если использовать Mocking и Stubbing для тестирования функции addJob, то код будет выглядеть так:
При таком подходе не определяется, корректно работает функция addJob или нет. Альтернативно можно написать код так:
Когда заменили на 4 JobData, то, определенно, результат в выражении expect будет тоже 4 JobData. Поэтому не нужно определять корректно работает функция addJob или нет.
Подводя итоги, использование Faking может быть более эффективно, чем Mocking, в случаях, похожих на этот.
В следующей статье рассмотрим наиболее часто встречающиеся ошибки в тестировании.
Подписывайтесь на телеграм-канал Flutter. Много, чтобы не пропустить новый выпуск и еще много всего интересного о кроссплатформенной разработке.
Название техники забавное) Всего одна буква и название становится описанием тестирования, когда в нем что-то идет не так 😂