2014-04-03 23 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