Недавно я обнаружил, что работаю в кодовой базе JavaScript, где мне нужно было реализовать новые шутки. В то время я очень мало знал о написании тестов, поэтому я посмотрел на Jest Docs и существующие шаблоны в кодовой базе, чтобы выяснить лучшие практики и как это сделать. Это было довольно простым, и я даже наслаждался, наслаждаясь тестированием. Но я не мог за жизнью меня надежно высмеивать вызов API.
Документы казались ясными, и существующий код появился иметь хорошие узоры, но имелись просто так много способов издеваться. Существующие тесты использовали всевозможные методы издевательства, такие как jest.genmockfroomodual () , jest.spyon () и jest.mock () Отказ Иногда издевательства были встроены, иногда они были в переменных, а иногда они были импортированы и экспортированы в волшебные пути от таинственного __mocks__ папки. Я использовал эти методы взаимозаменяемо каждый раз, когда я получил взрыв доверия к пониманию, только чтобы найти себя натумя на разных методах и их последствиях. Я понятия не имел, что я делал.
Проблема
Проблема заключалась в том, что я пытался узнать, как бежать, прежде чем я даже знал, как идти. Jest имеет много мощных способов высмеивать функции и оптимизировать эти издевательства, но они все бесполезны, если вы не знаете, как сделать простой макет в первую очередь. И пока доказывая документация обеспечивает много великого понимания и техники, Я не мог выяснить, где начать Отказ
В этой статье я надеюсь дать вам абсолютные основы для замедления вызова API, чтобы вы могли извлечь выгоду из моего 2020 Hindsight (HEH). Если вы идете с ума, как я, потому что вы не можете понять, как Просто сделайте простой чертовски макет , Начало здесь…
(Примечание: код ниже был написан в Node.js, но концепции издевательства также применяются к Frontend JavaScript и модулям ES6)
Размоцированный код
Мы собираемся тестировать это getfirstalbumtitle () Функция, которая выбирает массив альбомов из API и возвращает заголовок первого альбома:
// index.js
const axios = require('axios');
async function getFirstAlbumTitle() {
const response = await axios.get('https://jsonplaceholder.typicode.com/albums');
return response.data[0].title;
}
module.exports = getFirstAlbumTitle;
… И вот наш первоначальный тест на высмеивание для этой функции, что проверяет функцию фактически возвращает заголовок первого альбома в списке:
// index.test.js
const getFirstAlbumTitle = require('./index');
it('returns the title of the first album', async () => {
const title = await getFirstAlbumTitle(); // Run the function
expect(title).toEqual('quidem molestiae enim'); // Make an assertion on the result
});
Тест выше делает свою работу, но тест фактически делает сетевой запрос на API при запуске. Это открывает тест до всех видов ложных негативов, если API не работает точно, как и ожидалось (например, изменения заказа списка, API снижается, машина DEV теряет сетевое соединение и т. Д.). Не говоря уже о том, что делают эти запросы в большом количестве тестов, могут принести ваш тест на медленное ползу.
Но как мы можем изменить это? Запрос API осуществляется с Axios в составе getfirstalbumtitle () Отказ Как в мире мы должны достичь внутри Функция и изменить поведение?
Издеваться в 3 шага
Хорошо, вот оно есть. Это большой секрет, который спас бы мне горы времени, когда я борелюсь с учебными издевательствами. Чтобы издеваться над вызовом API в функции, вам просто нужно сделать эти 3 шага:
1. Импортируйте модуль, который вы хотите издеваться в ваш тестовый файл. 2. jest.mock () модуль. 3. Использовать .mockresvedvalue (<издевался ответ>) издеваться от ответа.
Вот и все!
Вот как выглядит наш тест после этого:
// index.test.js
const getFirstAlbumTitle = require('./index');
const axios = require('axios');
jest.mock('axios');
it('returns the title of the first album', async () => {
axios.get.mockResolvedValue({
data: [
{
userId: 1,
id: 1,
title: 'My First Album'
},
{
userId: 1,
id: 2,
title: 'Album: The Sequel'
}
]
});
const title = await getFirstAlbumTitle();
expect(title).toEqual('My First Album');
});
Что тут происходит?
Давайте сломаем это вниз. Самая важная часть, чтобы понять здесь, является импорт и jest.mock () :
const axios = require('axios');
jest.mock('axios');
Когда вы импортируете модуль в тестовый файл, то вызовите его в jest.mock ( , у вас есть полный контроль над всеми функциями из этого модуля, Даже если они называются внутри другой импортированной функции Отказ Сразу после звонка jest.Mock («Axios») , Jest заменяет каждую функцию в модуле Axios с пустыми функциями «издевательства», которые по существу ничего не делают и возврат undefined :
const axios = require('axios');
jest.mock('axios')
// Does nothing, then returns undefined:
axios.get('https://www.google.com')
// Does nothing, then returns undefined:
axios.post('https://jsonplaceholder.typicode.com/albums', {
id: 3,
title: 'Album with a Vengeance'
})
Так что теперь, когда вы устранили поведение по умолчанию, вы можете заменить его собственным …
axios.get.mockResolvedValue({
data: [
{
userId: 1,
id: 1,
title: 'My First Album'
},
{
userId: 1,
id: 2,
title: 'Album: The Sequel'
}
]
});
Издеватые функции замены, которые вставлены в Axios. случиться с целым кучей прохладной сверхдержавы методов для контроля их поведения! Самый важный здесь, для целей простого новичка, это .mockresvedvalue. () . Когда вы называете это в издеващемся методе, все, что вы передаете, станет значением возврата по умолчанию, когда издевалась функция вызывается для оставшейся части теста. Проще говоря: вы можете сделать axios.get () Верните все, что вы хотите! И Неважно, вызывается ли он непосредственно в вашем тестовом файле или как часть функции, импортированной в ваш тест – шума будет высмеивать функцию, независимо от того, где это называется!
Используйте эту новую силу, чтобы дать вашим функциям именно то, что они должны ожидать от вызовов API. Хватит беспокоиться о том, что сетевые запросы возвращаются, и просто сосредоточиться на том, что делает ваш код после того, как он получает ответ!
Если вы хотите играть с примерами, не стесняйтесь использовать этот демократию:
Zaklaughton/Simple-API-Mocking-With
Простой пример издевательства API с шумом.
Упаковка
Там у вас есть! Это самые основы того, что вам нужно для насмешки функций из другого модуля: Импортировать модуль, jest.mock () Модуль, затем вставьте свои собственные возвратные значения с помощью .mockresvedvalue. () !
Я рекомендую начать здесь, используя Только Эти методы, поскольку вы начинаете строить свои первые издевательства для ваших сетевых звонков. Как только у вас есть основополагающее понимание того, что происходит здесь, вы можете постепенно начать добавлять другие надежные функции для насмешек издевательства в, входящие в себя.
Смотрите также: Модули издевательства (Jest документация).
Редактировать: Кроме того, обязательно очистите свои издевательства между тестами, работающими jest.resetallmocks () после каждого теста. Это поможет убедиться, что ваши издеватели не будут мешать будущим тестам. (Спасибо за то, что указываете на это, @mjeffe !)
Куда пойти отсюда
Хорошо, вы узнали основы издевательства и успешно реализовали стратегии выше в нескольких тестах. Вы можете импортировать и мочать разрешенные значения для всех ваших вызовов API, как старый Pro. Что дальше?
Хотя методы, описанные выше, будут охватывать наиболее простые случаи использования, имеет множество издевающихся функциональных возможностей и методов, чтобы сделать некоторые действительно мощные вещи. Вы можете постепенно добавить некоторые концепции ниже, чтобы супер зарядить ваши изделы:
- Ознакомьтесь с другими методами функции MOCK, перечисленные в Jest Docs: Мачные функции Отказ Вы можете использовать такие методы, как
MockreturnedValue ()Макет синхронных возвратов иmockresvedvalueonce ()Чтобы только вернуть ценность в первый раз, когда он называется. - Хотите увидеть, сколько раз называется издевалась функция, с чем она называлась, а что он вернулся? Проверьте
mock.callsиmock.resultsСвойства (также в документации по функциям Mock ) У вас есть собственные пользовательские функции, которые делают сетевые запросы? Вы также можете поднять свои собственные модули после того, как они импортируются в тестовый файл: - jest.mock (‘./Путь/к/js/модуль/file’)
Действительно Здесь осторожно, хотя вы только издеваетесь, что нужно. Ваши тесты должны убедиться, что ваши функции делают то, что ожидается с заданным входом издевательства, и его можно легко завершить письменные тесты, которые вместо этого просто подтвердите, что вы проходили в издевательствах данных.Хотите действовать, чтобы действовать как изначально написана, но все же хочется посмотреть, сколько раз его назвали? Проверьте - jest.spyon () Отказ Ознакомьтесь о том, чтобы издеваться над одной и той же функцией и снова в нескольких тестах? Дайте ему макет по умолчанию в
- __mocks__
Папки с использованиемРучные издевательства Действительно
Я надеюсь, что это спасает других некоторых из потраченных впустую время и разочарования, через которое я прошел! Если ничего не имеет смысла здесь, пожалуйста, оставьте комментарий, и я был бы рад попытаться ответить на любые вопросы. Также дайте мне знать, если есть что-то еще, что помогло у вас есть «ага!» момент, учась издеваться!
Оригинал: “https://dev.to/zaklaughton/the-only-3-steps-you-need-to-mock-an-api-call-in-jest-39mb”