【问题标题】:How to make authenticated requests in mocha test using supertest and agent?如何使用 supertest 和 agent 在 mocha 测试中发出经过身份验证的请求?
【发布时间】:2023-03-17 17:21:01
【问题描述】:

我在登录后无法运行经过身份验证的测试(服务器返回 401 Unauthenticated)。

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

var user
    , user1;

describe('GET /api/jobs', function () {
    before(function (done) {
        user = new User({
            provider: 'local',
            name: 'Fake User',
            email: 'test@test.com',
            password: 'password'
        });

        // Clear users before testing
        User.remove().exec();

        request(app)
            .post('/api/users')
            .send(user)
            // end handles the response
            .end(function(err, res) {
                if (err) {
                    throw err;
                }

                res.should.have.status(200);
                res.body._id.should.exist;

                user1 = request.agent(app); //user1 will be used in all subsequent tests since he's supposed to be authenticated
                user1
                    .post('/api/session')
                    .send({ email: user.email, password: user.password })
                    .end(function(err, res) {
                        if ( err ) throw err;
                        // user1 will manage its own cookies
                        // res.redirects contains an Array of redirects
                        res.should.have.status(200);

                        done();
                    });
            });
    });

    afterEach(function (done) {
        User.remove().exec();
        done();
    });

    it('should create a job by user1', function (done) {
        var job = {
            //jobs stuff
        };

        user1
            .post('/api/jobs')
            .send(job)
            .expect(200) //It fails here, getting 401 Unauthenticated. Session is using passport local strategy
            .expect('Content-Type', /json/)
            .end(function (err, res) {
                if (err) return done(err);
                res.body.should.be.instanceof(Object);

                done();
            });
    });
});

会话正在设置这样的 cookie:

    if (req.user) {
        res.cookie('user', JSON.stringify(req.user.userInfo));
    }

【问题讨论】:

    标签: node.js tdd mocha.js restful-authentication supertest


    【解决方案1】:

    犯了一个愚蠢的错误。我使用before() 而不是beforeEach() 来创建和登录用户。

    beforeEach(function (done) {
    // do stuff before each test
    });
    

    afterEach() 正在删除数据库中的 Users

    如果有人感兴趣,这里是完整的解决方案:

    beforeEach(function (done) {
        // Clear data before testing
        user1 = {
            name: 'Fake User',
            username: 'test',
            email: 'test@test.com',
            password: 'password'
        };
    
        user2 = {
            name: 'Fake User2',
            username: 'test2',
            email: 'test2@test.com',
            password: 'password2'
        };
    
        job = {
            email: 'job@test.com'
            , title: 'Title'
            , description: 'Job description that is at least 60 characters with much detail'
            , apply: 'Application instructions'
            , company: 'Company'
            , location: 'Location'
        };
    
        function createUser1(cb){
            agent1
                .post('/api/users')
                .send(user1)
                .expect(200)
                .end(function(err, res){
                    if ( err ) throw err;
    
                    loginUser1.call(null, cb);
                });
        }
    
        function loginUser1(cb){
            agent1
                .post('/api/session')
                .send({
                    email: user1.email
                    , password: user1.password
                })
                .expect(200)
                .end(function(err, res){
                    if ( err ) throw err;
    
                    loggedInUser1 = res.body;
    
                    cb();
                });
        }
    
        function createUser2(cb){
            agent2
                .post('/api/users')
                .expect(200)
                .send(user2)
                .end(function(err, res){
                    if (err) throw err;
    
                    loginUser2.call(null, cb);
                });
        }
    
        function loginUser2(cb){
            agent2
                .post('/api/session')
                .send({
                    email: user2.email
                    , password: user2.password
                })
                .end(function(err, res){
                    if ( err ) throw err;
    
                    loggedInUser2 = res.body;
    
                    cb();
                });
        }
    
        async.series([function(cb){
            createUser1(cb);
        }, function(cb){
            createUser2(cb);
        }], done);
    
        //working, but looks like shiet with callbacks
        //      agent1
        //          .post('/api/users')
        //          .send(user1)
        //          .expect(200)
        //          // end handles the response
        //          .end(function(err, res) {
        //              if (err) throw err;
        //
        //              agent1
        //                  .post('/api/session')
        //                  .send({
        //                      email: user1.email
        //                      , password: user1.password
        //                  })
        //                  .expect(200)
        //                  .end(function(err, res) {
        //                      if ( err ) throw err;
        //
        //                      loggedInUser1 = res.body;
        //
        //                      //login the 2nd user
        //                      agent2
        //                          .post('/api/users')
        //                          .expect(200)
        //                          .send(user2)
        //                          // end handles the response
        //                          .end(function(err, res) {
        //                              if (err) throw err;
        //
        //                              agent2
        //                                  .post('/api/session')
        //                                  .send({
        //                                      email: user2.email
        //                                      , password: user2.password
        //                                  })
        //                                  .end(function(err, res) {
        //                                      if ( err ) throw err;
        //
        //                                      loggedInUser2 = res.body;
        //
        //                                      done();
        //                                  });
        //                          });
        //                  });
        //          });
    });
    
    afterEach(function (done) {
        User.remove()
            .execQ()
            .then(function(){
                return Job.remove().execQ()
            })
            .done(function(){
                done();
            });
    });
    

    agent1 是作为承诺对象的请求。

    var requestp = require("supertest-as-promised");
    var agent1 = requestp.agent(app)
    

    【讨论】:

    • 你的“agent1”来自哪里??
    • var requestp = require("supertest-as-promised")var agent1 = requestp.agent(app)
    • 你能解释一下cb吗,我有点困惑它是什么以及它是什么?
    • cb 只是回调的占位符。它是您传入的函数,它在获取用户后执行。不过,现在使用 async/await 有更好的方法来做到这一点。
    猜你喜欢
    • 2016-03-20
    • 2018-08-24
    • 2017-01-29
    • 1970-01-01
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 2019-12-01
    • 2010-10-05
    相关资源
    最近更新 更多