Тестирование запросов, которые перенаправляются с помощью mocha/supertest в node
Я не могу получить следующий интеграционный тест для передачи в экспресс-проекте, используя mocha, supertest и should (и coffeescript).
Тест
should = require('should')
request = require('supertest')
app = require('../../app')
describe 'authentication', ->
describe 'POST /sessions', ->
describe 'success', (done) ->
it 'displays a flash', (done) ->
request(app)
.post('/sessions')
.type('form')
.field('user', 'username')
.field('password', 'password')
.end (err, res) ->
res.text.should.include('logged in')
done()
Соответствующий код приложения
app.post '/sessions', (req, res) ->
req.flash 'info', "You are now logged in as #{req.body.user}"
res.redirect '/login'
Отказ
1) authentication POST /sessions success displays a flash:
AssertionError: expected 'Moved Temporarily. Redirecting to //127.0.0.1:3456/login' to include 'logged in'
Очевидно, что код приложения ничего полезного не делает. Я просто пытаюсь пройти тест.
Полагая математическое ожидание (res.text.should.include('logged in')
) вне функции конца и внутри функции expect
, получаются те же результаты. Я также попробовал вариант вызовов функций, например, удаление вызова .type('form')
и использование .send(user: 'username', password: 'password')
вместо двух вызовов .field()
.
Если это что-то значит, отправка запроса POST-запроса в приложение, когда он выполняется локально, дает тот же результат (Moved Temporarily. Redirecting to //127.0.0.1:3456/login
)
У меня такое чувство, что это тривиальная ошибка. Возможно, что-то я забыл в коде приложения или тестовом коде.
Любые предложения?
EDIT 1: Также стоит отметить, что при нажатии кнопки отправки в браузере я получаю ожидаемые результаты (флэш-сообщение).
РЕДАКТИРОВАТЬ 2: Дальнейшее исследование показывает результат любых результатов перенаправления в тело ответа Moved Temporarily. Redirecting to ...
. Это заставляет меня задаться вопросом, есть ли проблема в том, как я экспортирую приложение в app.js.
var express = require('express')
var app = express();
module.exports = app;
Ответы
Ответ 1
Для всех, кто попадает на эту страницу, ответ на этот вопрос довольно прост. Тело ответа Moved Temporarily.
- это то, что возвращается от supertest. Подробнее см. вопрос.
Подводя итог, я закончил делать что-то вроде этого.
should = require('should')
request = require('supertest')
app = require('../../app')
describe 'authentication', ->
describe 'POST /sessions', ->
describe 'success', ->
it 'redirects to the right path', (done) ->
request(app)
.post('/sessions')
.send(user: 'username', password: 'password')
.end (err, res) ->
res.header['location'].should.include('/home')
done()
Просто убедитесь, что заголовок ответа location
- это то, что вы ожидаете от него. Тестирование флеш-сообщений и просмотр конкретных интеграционных тестов должно проводиться с использованием другого метода.
Ответ 2
Для этого в supertest
есть встроенное утверждение:
should = require('should')
request = require('supertest')
app = require('../../app')
describe 'authentication', ->
describe 'POST /sessions', ->
describe 'success', ->
it 'redirects to the right path', (done) ->
request(app)
.post('/sessions')
.send(user: 'username', password: 'password')
.expect(302)
.expect('Location', '/home')
.end(done)
Ответ 3
Я пытался написать некоторые интеграционные тесты для перенаправленных запросов, и нашел хороший пример автором самого модуля здесь.
В примере TJ он использует цепочку, поэтому я тоже использовал что-то подобное.
Рассмотрим сценарий, в котором пользователь, зарегистрированный в сети, перенаправляется на домашнюю страницу при выходе из него.
it('should log the user out', function (done) {
request(app)
.get('/logout')
.end(function (err, res) {
if (err) return done(err);
// Logging out should have redirected you...
request(app)
.get('/')
.end(function (err, res) {
if (err) return done(err);
res.text.should.not.include('Testing Tester');
res.text.should.include('login');
done();
});
});
});
В зависимости от того, сколько редиректов у вас есть, вам может потребоваться вложить несколько обратных вызовов, но пример TJ должен быть достаточным.
Ответ 4
describe 'authentication', ->
describe 'POST /sessions', ->
describe 'success', (done) ->
it 'displays a flash', (done) ->
request(app)
.post('/sessions')
.type('form')
.field('user', 'username')
.field('password', 'password')
.redirects(1)
.end (err, res) ->
res.text.should.include('logged in')
done()
redirects()
будет следовать перенаправлению, чтобы вы могли выполнять обычные тесты просмотра.