Автор оригинала: Jani Hartikainen.
Этот урок Node.js проведет вас через то, как настроить инструмент тестирования, как установить проверку ваших HTTP Get и Post запросов, а также о том, как тестировать сценарий сбоя.
У меня есть приложение Node.js, где я хотел, чтобы установить тестирование некоторых HTTP-запросов. Узел обычно делает вещи простыми, поэтому я тоже ожидал, что это будет так … но я вскоре обнаружил, что это вообще не так.
Когда модульное тестирование, вы не хотите, чтобы HTTP-запросы выйдут и повлиять на результат. Вместо этого вы создаете поддельный запрос – тест двойной – заменить реальный, но потому что потоки узла трудно подделать, это где я попал в стену.
Это заняло некоторую работу, но нашел способ сделать это просто! Позвольте мне показать вам, как с некоторыми примерами на основе реального живого производственного кода.
- Отправка запроса на запрос на получение запроса и тестирование
- Отправка почтового запроса и тестирование поведения параметра
- Тестирование того, что сбои обрабатываются правильно
Пример сценария
Я основал это и тесты на реальный World Code и упростив их, поэтому их легко следовать. Но основные методы такие же, как я использую в реальном производственном коде.
Я собираюсь позвонить в этот файл API.JS.
var http = require('http'); module.exports = { get: function(callback) { var req = http.request({ hostname: 'jsonplaceholder.typicode.com', path: '/posts/1' }, function(response) { var data = ''; response.on('data', function(chunk) { data += chunk; }); response.on('end', function() { callback(null, JSON.parse(data)); }); }); req.end(); }, post: function(data, callback) { var req = http.request({ hostname: 'jsonplaceholder.typicode.com', path: '/posts', method: 'POST' }, function(response) { var data = ''; response.on('data', function(chunk) { data += chunk; }); response.on('end', function() { callback(null, JSON.parse(data)); }); }); req.write(JSON.stringify(data)); req.end(); } };
Это должно выглядеть знакомым, если вы использовали HTTP-модуль. Одна функция для получения данных, другая для отправки данных. Код использует API JSON API JSON, простой API для отдыха полезен для такого рода прототипирования и тестирования.
Необходимые библиотеки
Чтобы прославить тестирование, мы будем использовать некоторые библиотеки, чтобы помочь. Мы будем использовать Mocha в качестве структуры тестирования и SINON, чтобы создать тестовые удваивания. Потоки – это хлопот, но мы можем использовать Mock-Req и Mock-Res, чтобы исправить это.
NPM Установите Mocha Sinon Mock-Req Mock-Res
Настройка тестового набора
Во-первых, давайте создадим тестовый набор. Я собираюсь поставить этот файл в Тесты/APISPEC.JS
Отказ
var assert = require('assert'); var sinon = require('sinon'); var MockReq = require('mock-req'); var MockRes = require('mock-res'); var http = require('http'); var api = require('../api.js'); describe('api', function() { beforeEach(function() { this.request = sinon.stub(http, 'request'); }); afterEach(function() { http.request.restore(); }); //We will place our tests cases here });
Ключевые вещи здесь – Rebedeach
и ДОПОЛЮЧЕНИЕ
Отказ Rebedeach
Создает заглушку для замены http.request
и ДОПОЛЮЧЕНИЕ
Восстанавливает оригинальную функциональность.
STUB – это тестовый двойной, который позволяет нам определить поведение и использование трека – установить значения возврата, параметры, проверьте счетчик вызова и т. Д.
Но как эта помощь? Мы создали здесь заглушку, а не в модуле API! Nodejs кэширует необходимые модули, поэтому изменения здесь отражены в других модулях. Другими словами, API.Js вынужден использовать нашу заглушку.
Мы сохраняем заглушку в Это .Ревес
Итак, мы можем ссылаться на это позже.
Тестирование запроса Get
Давайте начнем с добавления теста, который подтверждает обработку запроса. Когда код работает, он звонит http.request
Отказ Так как мы ограблены, идея мы будем использовать контроль загрязнения, что происходит, когда http.request
Используется, чтобы мы могли воссоздать все сценарии без реального HTTP-запроса, когда-либо происходящего.
it('should convert get result to object', function(done) { var expected = { hello: 'world' }; var response = new MockRes(); response.write(JSON.stringify(expected)); response.end(); var request = new MockReq(); this.request.callsArgWith(1, response) .returns(request); api.get(function(err, result) { assert.deepEqual(result, expected); done(); }); });
Во-первых, мы определяем ожидаемые данные, которые мы будем использовать в нашем тесте и создать объект отклика Mock. Чтобы скопировать, как работает http.request, мы пишем json версию наших ожидаемых данных в ответ и заканчиваю ее.
Мы создаем просьбу издевательства, но нам нужно только как возвращаемое значение.
Успешный HTTP.Request пройдет ответ на обратный вызов. Глядя на более раннее пример, обратный вызов – это второй параметр, поэтому мы скажем острую назвать его с помощью ответа в качестве параметра. Нумерация начинается с 0, поэтому использование 1 относится ко второму параметру. Звонок на http.request
Всегда возвращает запрос, поэтому мы скажем это, чтобы вернуть наш запрос MOCK.
С настройкой из пути мы называем API.GET
с обратным вызовом, который проверяет поведение. Модуль Assert находится встроенный в узел, но если вы предпочитаете использовать вашу любимую библиотеку утверждения, такие как Chai, вместо этого.
Мы можем запустить тест, используя моча
Отказ Вы должны найти тест пропуски с зеленым светом.
Тестирование запроса после
Для сценария Post мы хотим убедиться, что параметры правильно передаются на запрос HTTP.
it('should send post params in request body', function() { var params = { foo: 'bar' }; var expected = JSON.stringify(params); var request = new MockReq({ method: 'POST' }); var write = sinon.spy(request, 'write'); this.request.returns(request); api.post(params, function() { }); assert(write.withArgs(expected).calledOnce); });
При звонке API.POST
, он должен отправлять параметры в тело запроса. Вот почему в этом тесте нам нужно только проверить request.write
называется с правильным значением.
Как и ранее, мы сначала определяем ожидаемые данные. Это помогает сделать тест легче поддерживать, так как мы не используем магические значения по всему месту.
Затем мы определяем просьбу издевательства, убедившись, что он использует метод Post. Чтобы убедиться, что ожидаемые данные написаны, нам нужен способ проверить, как называется функция. Это призывает к другому тесту двойным, в данном случае шпион. Также как настоящие тайные агенты, шпион даст нам информацию о своей цели – в этом случае функция записи.
http.request
Функция требуется только для возврата издеватого запроса в этот тест.
Мы называем API.POST
, прохождение в наших параметрах и пустой обратный вызов. Почему пустой обратный вызов? Опять же, мы только проверяем, что нам нужно, и здесь нам не нужно проверять обратный вызов.
Наконец, мы используем Assert, чтобы проверить значения из шпиона: мы проверяем, что SPY назывался один раз с правильными параметрами.
Мы можем снова запустить тесты, используя моча
и они пройдут.
Примечание: В реальном приложении вы можете получить тест на обратный вызов, но он должен идти в свой собственный тест. Один тестовый случай должен идеально иметь только одно утверждение. Тест на обратный вызов будет напоминать тест с помощью запроса на получение, поэтому я не буду подробно описан здесь.
Тестирование сценария отказа
И последнее, но не менее важное, мы должны включить тест на неудачу.
Каждая другая библиотека тестирования HTTP я пыталась наткнуться здесь, но с Mock-req это просто.
it('should pass request error to callback', function(done) { var expected = 'some error'; var request = new MockReq(); this.request.returns(request); api.get(function(err) { assert.equal(err, expected); done(); }); request.emit('error', expected); });
Это должно быть начать выглядеть знакомым. Мы определяем ожидаемые данные, создайте просьбу издевания, сообщите нашему заглушку, чтобы вернуть его и позвонить в API. Обратный вызов, переданный на API, проверяет параметр ошибки правильный.
Новая вещь здесь – последняя строка. Когда HTTP-запрос не удается из-за ошибок сетевых ошибок, ошибки диаграммы HTTP или такие, он испускает событие ошибки. Чтобы моделировать ошибку, мы испускаем один из теста.
Запустите тесты с моча, и они … не удастся? Хм?
Вот почему модульные тесты важны, и особенно тестирование случаев неудачи! Оказывается, ошибка сбрала в код.
Нет проблем, давайте добавим обработку для события ошибки.
get: function(callback) { var req = http.request({ hostname: 'jsonplaceholder.typicode.com', path: '/posts/1' }, function(response) { var data = ''; response.on('data', function(chunk) { data += chunk; }); response.on('end', function() { callback(null, JSON.parse(data)); }); }); req.on('error', function(err) { callback(err); }); req.end(); },
Единственное, что добавлено здесь, – три строки для обработки события ошибки. Запустите тесты с Mocha, и теперь они пройдут. Сделанный!
Заключение
Письменные тесты, такие как эти практики. Вам нужно знать, как работают укоренные и издеватые функции, но с опытом станет легким. Большое, что вы можете применить эти методы, чтобы проверить другие вещи – MySQL-запросы, поиск Redis, вызовы Ajax, разъемы TCP … Список продолжается и включен.
Я сделал пример модуля и тесты для загрузки отсюда для вашего удобства: API.JS , APISPEC.JS Отказ