2012-09-04 11 views
28

umleiten Ich kann nicht scheinen, den folgenden Integrationstest zu erhalten, um in einem Express-Projekt mit mocha, supertest und should (und coffeescript) zu übergeben.Testen von Anforderungen, die mit Mocha/Supertest in Knoten


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

Relevant Anwendungscode

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

Failure

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

Offensichtlich ist, dass der Anwendungscode nicht etwas Sinnvolles tun. Ich versuche nur, den Test zu bestehen.

Das Setzen der Erwartung (res.text.should.include('logged in')) außerhalb der Endfunktion und innerhalb der expect-Funktion führt zu denselben Ergebnissen. Ich habe auch eine Variante der Funktionsaufrufe versucht, zum Beispiel den .type('form') Anruf zu entfernen und .send(user: 'username', password: 'password') anstelle der zwei .field() Aufrufe zu verwenden.

Wenn es etwas bedeutet, eine Locke POST-Anfrage an den App zu senden, wenn es läuft lokal liefert die gleiche Leistung (Moved Temporarily. Redirecting to //127.0.0.1:3456/login)

Ich habe das Gefühl, das ist ein trivialer Fehler. Möglicherweise etwas, das ich im Anwendungscode oder im Testcode vergesse.

Irgendwelche Vorschläge?

EDIT 1: Es ist auch erwähnenswert, dass, wenn ich den Absenden-Button im Browser klicke, ich die erwarteten Ergebnisse (eine Flash-Nachricht) bekomme.

EDIT 2: Weitere Untersuchungen zeigt die Ausgabe des jede umlenken Ergebnisse im Moved Temporarily. Redirecting to ... Antworttext. Das lässt mich fragen, ob es ein Problem in der Art gibt, wie ich die App in app.js exportiere.

+0

Bitte werfen Sie einen Blick: http://StackOverflow.com/Questions/14001183/How-to-Authenticate-Supertest-Requests-with-Passport/37609721#37609721 –

Antwort

22

Für jeden, der auf diese Seite stößt, ist die Antwort auf diese Frage ziemlich einfach. Der Antworthauptteil Moved Temporarily. wird vom Supertest zurückgegeben. Weitere Informationen finden Sie unter the issue.

Zusammenfassend habe ich so etwas getan.

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

Überprüfen Sie einfach, dass die Antwort-Header location ist, was Sie erwarten, dass es sein. Das Testen auf Flash-Nachrichten und das Anzeigen spezifischer Integrationstests sollte mit einer anderen Methode durchgeführt werden.

+8

... welche andere Methode? – Alex

+3

Ich bin hier speziell, weil ich versucht habe zu tun "Das Testen auf Flash-Nachrichten und das Anzeigen spezifischer Integrationstests sollte mit einer anderen Methode durchgeführt werden." –

+0

Zusätzlich zum Überprüfen der Position in der Kopfzeile sollten Sie überprüfen, dass res.statusCode 302 (Redirect) ist. – thefinnomenon

2

Ich habe versucht, einige Integrationstests für Anfragen zu schreiben, die ebenfalls umgeleitet wurden, und fand ein gutes Beispiel vom Autor des Moduls selbst here.

In TJs Beispiel verwendet er Verkettung, also habe ich auch so etwas benutzt.

Betrachten Sie ein Szenario, in dem ein angemeldeter Benutzer umgeleitet wird auf die Homepage, wenn er oder sie abmeldet.

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

Je nachdem, wie viele Umleitungen Sie haben, können Sie ein paar Rückrufe zu nisten, aber TJ Beispiel sollte ausreichen.

18

Es ist eingebaut in Behauptung dafür in 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) 
1
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() 

Die redirects() wird die Umleitung folgen, so können Sie Ihre übliche Ansicht Tests durchführen.

+0

Dies kann ein alter Beitrag sein, aber die .redirects (1) funktionierte wunderbar, um einen Umleitungsfehler während des Tests zu beheben. Vielen Dank – SteveB