2012-09-04 12 views
28

中使用摩卡/超級終端重定向的測試請求我似乎無法使用mocha,supertestshould(和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

我有一種感覺,這是一個很小的錯誤。可能是我在應用程序代碼或測試代碼中忘記的東西。

有什麼建議嗎?

編輯1:也值得注意的是,當點擊瀏覽器中的提交按鈕時,我會得到預期的結果(一條flash消息)。

編輯2:進一步的調查顯示任何重定向在Moved Temporarily. Redirecting to ...響應身體的結果的輸出。這讓我想知道在app.js中導出應用程序的方式是否存在問題。

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

module.exports = app; 
+0

請看看:http://stackoverflow.com/questions/14001183/how-to-authenticate-supertest-requests-with-passport/37609721#37609721 –

回答

22

對於任何遇到此頁面的人來說,這個問題的答案都很簡單。 Moved Temporarily.響應正文是從超級用戶返回的內容。有關更多詳細信息,請參閱the issue。總結一下,我最終做了這樣的事情。

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是你希望它是什麼。應該使用另一種方法測試閃存消息並查看特定的集成測試。

+8

...還有什麼其他方法? – Alex

+3

我在這裏具體是因爲我正在嘗試「使用其他方法來測試閃存消息並查看特定的集成測試。」 –

+0

除了檢查標題中的位置外,還應檢查res.statusCode是否爲302(重定向)。 – thefinnomenon

2

我正在嘗試爲重定向的請求編寫一些集成測試,並找到了模塊本身作者here的一個很好的例子。在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的例子應該足夠了。

18

還有就是內置的斷言這個在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() 

redirects()將遵循重定向,所以你可以做你通常的看法測試。

+0

這可能是一箇舊的帖子,但.redirects(1)在我測試時解決重定向錯誤的工作很好。謝謝 – SteveB