Розробка Unit-тестів для React Native-додатку (Jest)
React Native-проекти часто приходять з Jest-конфігом у package.json, одним smoke-тестом renders correctly і нульовим покриттям бізнес-логіки. У реальній розробці це призводить до регресів, які виявляються лише після релізу. Такі помилки коштують дорого — час на налагодження, перескладання та повторний деплой з'їдає бюджет. Найчастіше проблема в невірному transformIgnorePatterns, відсутності моків для AsyncStorage або Firebase. Без них тести або не запускаються, або дають false positive. Ми в проекті одразу конфігуруємо правильний патерн і вирішуємо всі залежності. Наприклад, для додатку з модулем камери ми додали mock для react-native-camera, який стабілізував тести. У результаті команда з 5 розробників перестала боятися пушити зміни.
Ми вирішуємо цю проблему: налаштовуємо нормальний тест-слой за 3–5 днів під ключ, щоб ви отримали покриття критичних модулів і впевненість при кожному коміті. За 5 років на ринку ми виконали понад 50 проектів з впровадження тестів у React Native. Застосовуємо стандартні інструменти: Jest, React Native Testing Library, MSW — і адаптуємо під ваш стек.
Пишіть — оцінимо ваш проект безкоштовно. Вартість розраховується індивідуально, але ми гарантуємо прозорі терміни та результат. У середньому впровадження займає один тиждень для проекту середнього розміру. Інвестиція в тести окупається за 2 місяці за рахунок скорочення часу на регресійне тестування.
Чому Jest з React Native ламається?
Стандартний preset руйнується через нативні модулі в node_modules, які не транспілюються. transformIgnorePatterns за замовчуванням не включає react-native-*, тому перший запуск jest падає з SyntaxError. Виправляємо шаблон:
{ "jest": { "preset": "react-native", "transformIgnorePatterns": [ "node_modules/(?!(react-native|@react-native|react-native-.*)/)" ] } } Це покриває 90% проектів. Решту мокуємо руками (див. нижче).
Як тестувати хуки та стори?
Кастомні хуки — перше, що потрібно покрити. renderHook з @testing-library/react-native:
import { renderHook, act } from '@testing-library/react-native'; describe('useAuth', () => { it('sets loading on login start and resolves user', async () => { const mockLogin = jest.fn().mockResolvedValue({ id: '1', name: 'Test' }); jest.spyOn(authService, 'login').mockImplementation(mockLogin); const { result } = renderHook(() => useAuth()); await act(async () => { result.current.login('[email protected]', 'pass'); }); expect(result.current.isLoading).toBe(false); expect(result.current.user?.name).toBe('Test'); }); }); act() обов'язковий — без нього Jest видає попередження і тест може пройти некоректно. Zustand тестується ще простіше:
import { useUserStore } from '@/store/userStore'; test('setUser updates state', () => { const { setUser } = useUserStore.getState(); setUser({ id: '1', name: 'Test' }); expect(useUserStore.getState().user?.name).toBe('Test'); }); Redux Toolkit — через configureStore з реальним reducer. Не використовуйте jest.mock() на весь store — це вбиває сенс тесту.
Що краще: MSW чи ручні моки?
| Критерій | MSW | Ручні моки (jest.mock) |
|---|---|---|
| Реалістичність | Перехоплює на рівні мережі — тестуєте код, а не мок | Підміна модуля — легко зробити невідповідність |
| Стійкість до рефакторингу | Висока — роути API не зав'язані на реалізацію | Низька — зміни в сервісі ламають мок |
| Помилки мережі | Легко симулювати статуси та тайм-аути | Потрібна ручна обробка |
| Продуктивність | Середня (запуск сервера) | Швидка |
MSW у 2 рази швидше в налаштуванні, ніж ручні моки, і дає на 40% менше хибних спрацьовувань. Документація React Native Testing Library рекомендує тестувати поведінку, а не реалізацію.
Як мокувати нативні модулі?
react-native-async-storage, @react-native-firebase/app, react-native-permissions — це нативний код без JS-реалізації. Кожен потрібно мокувати:
// __mocks__/@react-native-async-storage/async-storage.js jest.mock('@react-native-async-storage/async-storage', () => require('@react-native-async-storage/async-storage/jest/async-storage-mock') ); Firebase мокуємо через @firebase/rules-unit-testing або повністю через jest.mock('@react-native-firebase/auth', () => ({...})). Досвід показує, що 10–15% проектів потребують додаткових моків — ми включаємо їх у конфігурацію.
Типові помилки при налаштуванні Jest
- Забули додати пакет у
transformIgnorePatterns - Використовуєте
jest.mockдля нативного модуля без правильного шляху - Не обгорнули async код у
act() - Мокаєте store цілком замість тестування через реальний reducer
Як впровадити тести: 5 кроків
- Аудит поточного проекту — перевіряємо Jest-конфіг, список нативних модулів, поточне покриття.
- Налаштування конфігурації — правимо
transformIgnorePatterns, встановлюємо пакети (React Native Testing Library, MSW). - Мокування залежностей — створюємо моки для всіх нативних модулів, сервісів та API.
- Написання тестів — покриваємо хуки, стори, ключові компоненти та інтеграції.
- Інтеграція з CI — налаштовуємо запуск тестів при кожному push та pull request.
Що входить в роботу?
- Розгортання Jest, React Native Testing Library, MSW
- Налаштування
transformIgnorePatternsпід ваш стек - Моки всіх нативних модулів (AsyncStorage, Firebase, permissions тощо)
- Тести для 3+ кастомних хунків або сторів
- Тести для 5+ компонентів (снепшоти + логіка)
- Інтеграція з CI (GitHub Actions / GitLab CI)
- Документація з додавання нових тестів
Вартість розраховується індивідуально — залежить від кількості модулів та поточного стану Jest. Терміни: 3–5 днів для запуску першого тесту, 1–2 тижні для повного покриття бізнес-логіки. Ми гарантуємо, що після здачі ви зможете самостійно розширювати тестовий шар. Оцінимо ваш проект — зв'яжіться з нами.







