Подтвердить что ты не робот

Тестирование запросов, которые перенаправляются с помощью 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;
4b9b3361

Ответ 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() будет следовать перенаправлению, чтобы вы могли выполнять обычные тесты просмотра.