Утилита синглтонов для тестирования интеграции API

Общеизвестно, что синглтоны нелегко тестировать. Они нарушают некоторые правила ООП, и когда вы их используете, ваша кодовая база становится зависимой от них. Но недавно в моих работах над бэкэндом javascript мне нужно было протестировать интеграцию API со службой аутентификации OAuth2. Для такого рода службы требуется сохраненный клиент и пользователь в вашей базе данных, поэтому вы можете пройти аутентификацию, прежде чем делать запрос к другим маршрутам/ресурсам. Трудно поддерживать целостность данных между тестовыми примерами. Потому что моя среда тестирования Jest очищает базу данных mongoDB в памяти после каждого случая тестирования. Таким образом, несконцентрированный или неопытный разработчик может немного напортачить с реализацией тестов.

Итак, начнем сначала…

В моем приложении есть схема GraphQL, которая управляет пользователями и лицами, реализованная с помощью тестов для каждой мутации и запроса. Поэтому я начинаю реализацию OAuth2 с функции разрешений (администратор, менеджер, общий и посетитель). И запрещены любые запросы к маршруту /graphql, если пользователь не является аутентифицированным администратором. Теперь мне нужно создать клиент, создать пользователя-администратора, аутентифицировать его, добавить токен доступа в заголовок запроса, прежде чем снова использовать мои тесты.

Одиночки…

был использован для выполнения этой работы для меня. Я создал синглтон для клиента и еще один для пользователя. Для клиента он возвращает только объект Client в своем методе getClient. Если экземпляр клиента не создан, новый клиент создается и возвращается из этого метода. Для User Singleton я сделал немного сложнее. Чтобы упростить тестирование, я храню в этом синглтоне 4 пользовательских объекта, по одному для каждого разрешения (таким образом я могу вызвать getAdmin() для создания тестового примера с пользователем-администратором). У каждого есть метод reset(), потому что каждый тест очищает базу данных, аннулируя любой сохраненный объект моими синглтонами.

Абстракция тестов

Я сделал это таким образом, чтобы абстрагироваться от всей вышеупомянутой логики и упростить тестирование с различными типами пользователей. После выполнения всех реализаций мои файлы тестовых случаев увеличились только на две строки и пару строк (для выбора типа пользователя). Вся моя прединтеграционная логика для тестирования уже была абстрагирована в модуль замыкания javascript. Этот модуль получил новую функцию «сброса», которая выполняет метод сброса всех синглетонов. И они выполняются внутри функции перед очисткой базы данных внутри моего метода afterEach().

Выводы

Мне нравится, насколько лексическим теперь стало тестирование для каждого типа пользователей. Но если подумать о том, сколько усилий я приложил, чтобы некоторые могли сказать, что оно того не стоит, мне все равно нужно создать тестовый пример для каждого из созданных клиентов и пользователей. К счастью, мне нужно было создать его только один раз, потому что все мои тесты работают с разрешениями Oauth2 +, что не так просто заставить его работать. И если в будущем будет создана какая-либо другая функция, выполнение тестов будет таким же простым, как сейчас.

Спасибо за чтение! :)