2

从我读过的所有文档和示例中,应该可以使用代理在超测中保持会话:

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: 'duchess@isis.com',
    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();
            });

    });
});

会话应该持续存在,因为上面的每个请求都使用相同的代理。然而,情况似乎并非如此 - set-cookie 日志的输出如下:

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

passport.js 用于身份验证和会话。我希望上面的 connect.sid 对于两个请求都是恒定的,但看起来每次调用都会创建一个新会话,因此代理在第二次调用时没有登录,也没有返回任何用户对象。

当我在浏览器中手动测试我的应用程序时,connect.sid 在登录后保持不变,并且我正在测试的功能确实有效。

我一定是在代理方面做错了,我希望有人能发现它。否则,我将不胜感激有关如何调试该问题的建议。

4

2 回答 2

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();
                });
        });
});
于 2014-04-04T01:47:22.583 回答
1

Esteban 的建议指出我忽略了代码的异步特性。回到这个例子,我意识到我错过了在单独的测试中登录的重要性;这样做解决了我的问题。

虽然我现在正在创建依赖测试,但我对此并不着迷。

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: 'duchess@isis.com',
    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();
});
});
于 2014-04-04T03:39:39.000 回答