2014-04-03 75 views
0

從所有的文件和我讀過的例子,應該可以使用代理supertest堅持一個會話:supertest劑似乎並沒有堅持的Node.js應用express.js會議

var app = require('../../../server'), 
    should = require('should'), 
    request = require('supertest'), 
    mongoose = require('mongoose'), 
    User = mongoose.model('User'), 
    _ = require('lodash'); 

var user = { 
    name: 'Sterling Archer', 
    email: '[email protected]', 
    password: 'guest' 
}; 

describe('user.me', function() { 

    var url = '/user'; 
    var agent = request.agent(app); 
    var new_user = new User(user); 
    new_user.save(); 

    it('should return a user object', function(done) { 

     agent 
      .post('/signin') 
      .send(_.omit(user, 'name')) 
      .expect(200).end(function(err, res) { 
       console.log(res.headers['set-cookie']); 
      }); 

     agent 
      .get(url) 
      .expect(200) 
      .end(function(err, res) { 
       should.not.exist(err); 
       console.log(res.headers['set-cookie']); 
       res.body.should.have.property('user'); 
       res.body.user.should.have.properties('name', 'email'); 
       done(); 
      }); 

    }); 
}); 

由於上面的每個請求都使用相同的代理,因此會話應該保留。然而這似乎並不如此 - 從設置cookie的日誌輸出如下:被用於認證和會話

[ 'connect.sid=s%3AsFl1DQ4oOxC8MNAm79mnnr9q.gMkp8iEWtG8XlZZ2rkmheBwxKAyLyhixqDUOkYftwzA; Path=/; HttpOnly' ] 
[ 'connect.sid=s%3AEzfbPyRGMff7yBXc9OAX3vGT.Ze2YoxZzuB6F6OwOk7mvrk96yPP2G4MGV%2Bt1rVjTyS8; Path=/; HttpOnly' ] 

passport.js。我希望上面的connect.sid對於這兩個請求都是恆定的,但是看起來每個呼叫都會創建一個新的會話,這樣代理在第二次呼叫時就不會登錄,並且不會返回任何用戶對象。

當我在瀏覽器中手動測試我的應用程序connect.sid在登錄後保持不變並且我測試的功能確實有效。

我一定在代理方面做錯了什麼,我希望有人能發現它。否則,關於如何調試該問題的建議將非常感謝。

+0

'.set('Cookie',)'方法在第二個座席調用,它工作嗎? – Gntem

+0

我曾嘗試設置Cookie,因爲我在其他一些示例中看到了該方法。但是,它不應該是必要的,也不會工作。 set()會在第一次調用完成之前在第二個代理程序上調用(因此cookie值將不可用)。 – Matt

回答

1

埃斯特班的建議指出,我忽視了代碼的異步性。回到this example我意識到我錯過了在單獨測試中登錄的重要性;這樣做解決了我的問題。

雖然我現在正在創建依賴測試,但我並不是瘋狂的。

var app = require('../../../server'), 
    should = require('should'), 
    request = require('supertest'), 
    mongoose = require('mongoose'), 
    User = mongoose.model('User'), 
    _ = require('lodash'); 

var user = { 
    name: 'Sterling Archer', 
    email: '[email protected]', 
    password: 'guest' 
}; 

var agent = request.agent(app); 

describe('User Controller', function() { 

before(function(done) { 
    var new_user = new User(user); 
    new_user.save(); 
    done(); 
}); 

describe('user.signin', function() { 

    var url = '/signin'; 

    it('should signin and return a user object', function(done) { 
     agent 
      .post(url) 
      .send(_.omit(user, 'name')) 
      .expect(200) 
      .end(function(err, res) { 
       should.not.exist(err); 
       res.body.should.have.property('user'); 
       res.body.user.should.have.properties('name', 'email'); 
       done(); 
      }); 
    }); 
}); 

describe('user.me', function() { 

    var url = '/user'; 

    it('should return a user object', function(done) { 
     agent 
      .get(url) 
      .expect(200) 
      .end(function(err, res) { 
       should.not.exist(err); 
       res.body.should.have.property('user'); 
       res.body.user.should.have.properties('name', 'email'); 
       done(); 
      }); 
    }); 
}); 

after(function(done) { 
    User.remove().exec(); 
    done(); 
}); 
}); 
+1

你的工作很棒!我想我知道爲什麼這樣工作,但沒有時間去測試它,不幸的是(提示:當'end'調用你的回調代理沒有管理'set-cookie'頭部時)。通過將登錄放入'before'函數而不是其他測試(儘管測試登錄仍然是一個好主意),我會改進您的解決方案。 – Esteban

+1

我剛剛發現你是[這個bug]的受害者(https://github.com/visionmedia/superagent/issues/314)。幸運的是,已經發出拉取請求來修復它。 – Esteban

4

您正在發送第二個請求,而沒有等待第一個響應;如果您不讓代理在響應中接收Set-Cookie頭並在相同請求中將其值用作Cookie頭,則會創建新會話。試試吧:

it('should return a user object', function(done) { 

    agent 
     .post('/signin') 
     .send(_.omit(user, 'name')) 
     .expect(200).end(function(err, res) { 
      console.log(res.headers['set-cookie']); 
      agent 
       .get(url) 
       .expect(200) 
       .end(function(err, res) { 
        should.not.exist(err); 
        console.log(res.headers['set-cookie']); // Should print nothing. 
        res.body.should.have.property('user'); 
        res.body.user.should.have.properties('name', 'email'); 
        done(); 
       }); 
     }); 
}); 
+0

您的建議無效,但您確實指出我忽略了代碼的異步性質。我曾經嘗試過一次;儘管我現在對發生的事情有了更好的理解,但我不明白爲什麼這也不起作用!再次,不同的cookie被記錄下來(甚至在你評論過它應該不打印的地方)。但是,我找到了一個解決方案,見下文。 – Matt