web-dev-qa-db-fra.com

Test des requêtes qui redirigent avec mocha / supertest dans le nœud

Je n'arrive pas à obtenir le test d'intégration suivant pour passer dans un projet express en utilisant mocha , supertest , et should (and coffeescript).


Le test

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()

Code d'application pertinent

app.post '/sessions', (req, res) ->
  req.flash 'info', "You are now logged in as #{req.body.user}"
  res.redirect '/login'

Échec

1) authentication POST /sessions success displays a flash:
   AssertionError: expected 'Moved Temporarily. Redirecting to //127.0.0.1:3456/login' to include 'logged in'

De toute évidence, le code d'application ne fait rien d'utile. J'essaie juste de réussir le test.

Placer l'attente (res.text.should.include('logged in')) en dehors de la fonction de fin et à l'intérieur de la fonction expect donne les mêmes résultats. J'ai également essayé une variante des appels de fonction, par exemple en supprimant l'appel .type('form') et en utilisant .send(user: 'username', password: 'password') au lieu des deux appels .field().

Si cela signifie quelque chose, l'envoi d'une boucle POST demande à l'application lorsqu'elle s'exécute localement donne la même sortie (Moved Temporarily. Redirecting to //127.0.0.1:3456/login)

J'ai le sentiment que c'est une erreur insignifiante. Peut-être quelque chose que j'oublie dans le code d'application ou le code de test.

Aucune suggestion?

EDIT 1: Il convient également de noter qu'en cliquant sur le bouton Envoyer dans le navigateur, j'obtiens les résultats attendus (un message flash).

EDIT 2: Une enquête plus approfondie montre la sortie de any résultats de redirection dans le corps de réponse Moved Temporarily. Redirecting to .... Cela me fait me demander s'il y a un problème dans la façon dont j'exporte l'application dans app.js.

var express = require('express')
var app = express();

module.exports = app;
36
Feech

Pour quiconque tombe sur cette page, la réponse à cette question est assez simple. Le Moved Temporarily. le corps de réponse est ce qui est renvoyé par le supertest. Voir le problème pour plus de détails.

Pour résumer, j'ai fini par faire quelque chose comme ça.

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()

Vérifiez simplement que l'en-tête de réponse location correspond à ce que vous attendez. Les tests de messages flash et les tests d'intégration spécifiques doivent être effectués à l'aide d'une autre méthode.

25
Feech

Il y a une assertion intégrée pour cela dans 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)
25
Blacksonic
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()

La redirects() suivra la redirection afin que vous puissiez faire vos tests de vue habituels.

3
super_noobling

J'essayais d'écrire des tests d'intégration pour les requêtes qui étaient également redirigées, et j'ai trouvé un bon exemple par l'auteur du module lui-même ici .

Dans l'exemple de TJ, il utilise le chaînage, alors j'ai également utilisé quelque chose comme ça.

Considérons un scénario dans lequel un utilisateur connecté est redirigé vers la page d'accueil lorsqu'il se déconnecte.

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();
        });
    });
});

Selon le nombre de redirections dont vous disposez, vous devrez peut-être imbriquer quelques rappels, mais l'exemple de TJ devrait suffire.

2
JohnnyCoder