MOCK-ОБ'ЄКТИ В ЮНІТ-ТЕСТУВАННІ
12.10.2021 23:51
[1. Информационные системы и технологии]
Автор: Глюза А.П., студентка, комп’ютерна інженерія та управління, Харківський національний університет радіоелектроніки, м. Харків
Тестування – це процес в програмуванні, що дозволяє перевірити на коректність окремі модулі вихідного коду програми.
Існує кілька підходів до визначення тестів. Перша модель – класика: спочатку розробка, а потім тестування «code first». Це означає, що спочатку відбувається написання коду, потім тестування продукту і відправка його або на доопрацювання, або перехід до наступної стадії розробки.
Інший підхід можна назвати «test first» режимом. Це означає, що тестування починається ще до написання самої функції – наприклад, створити одиничний тест або автоматично виконується набір тестів до того, як функція або якийсь шматок коду буде розроблений і впроваджений в додаток. Одним з найбільш популярних прикладів тут є Test-Driven Development.
Проте, варто згадати, що техніка «test first» не так популярна, як «code first». Це пов'язано з тим, що в більшості проектів все ще складно автоматизувати те, що ще не було розроблено. Узагальнюючи обидва згаданих вище підходу, можна зробити висновок, що немає особливої різниці і що автоматизацію тестів можна використовувати в будь-якому з варіантів.
Важливі терміни, з якими доводиться стикатися в процесі написання тестів – це стаб (stubs) і моки (mock).
Дуже часто код (функція, модуль) мають зовнішні залежності. Зовнішня залежність – це все, що робить тести не правдивими і складно-підтримуваними. Файлова система – залежність: структура каталогів може бути іншою на іншій машині. База даних – залежність, її може не бути на іншій машині. Веб-сервіс – залежність: може не бути інтернету.
Якщо на питання: «Чи буде цей компонент поводитися так само на іншій машині?», відповідь – «ні», то його необхідно «підмінити» і тут на допомогу якраз приходять стаб і моки. Але є й інша сторона медалі, коли розробник починає захоплюватися і приходить до того, що підміняє взагалі все. Відповідно тести перестають перевіряти сам додаток і починають тестувати стаб та моки. Це в корені не вірно. Якщо «живих» реалізацій в тесті немає, то цей тест не тестує нічого.
Іноді ці терміни stubs і mock плутають: різниця в тому, що стаб нічого не перевіряє, а лише імітує заданий стан. А мок – це об'єкт, у якого є очікування. Наприклад, що даний метод класу повинен бути викликаний певне число раз. Іншими словами, тест ніколи не зламається через стаб, а ось через мока може.
З технічної точки зору це означає, що, використовуючи стаб, ми перевіряємо стан тестованого класу або результат виконаного методу. При використанні мока ми перевіряємо, чи відповідають очікування мока поведінки тестованого класу. Також краще використовувати не більше одного мока на тест. Інакше з високою ймовірністю ви порушите принцип «тестувати тільки одну річ». При цьому, в одному тесті може бути скільки завгодно стабів або ж мок і стаб.
Є вже готові фреймворки, які надають такий функціонал: Sinon, Jasmine, enzyme, Jest, testdouble.
Незважаючи на те, що існують ситуації, в яких Моки потрібні, в більшості ситуацій їх потрібно уникати. Моки занадто багато знають про те, як працює код. Будь-який тест з моками з чорного ящика перетворюється в білий ящик. Повсюдне використання моков призводить до двох речей:
- після рефакторинга доводиться переписувати тести, навіть якщо код працює правильно. Відбувається це через зав'язки на те, як конкретно працює код;
- код може перестати працювати, але тести будуть проходити, тому що вони сфокусовані не на результатах його роботи, а на тому, як він влаштований всередині.
Література:
1. Mock-объект [Електронний ресурс] – Режим доступу до ресурсу: https://dic.academic.ru/dic.nsf/ruwiki/166069.
2. Модуль Mock: макеты-пустышки в тестировании [Електронний ресурс]. – 2012. – Режим доступу до ресурсу: https://habr.com/ru/post/141209/.