为什么我在测试中得到401响应?

时间:2015-10-14 14:30:00

标签: node.js express mocha supertest

我正在尝试在我的Node / Express / Mongoose后端测试带有身份验证的路由。

这是测试文件

    var should = require('should');
    var _ = require('lodash');
    var async = require('async');
    var app = require('../../../../app');
    var request = require('supertest');
    var mongoose = require('mongoose');
    var User = mongoose.model('User');
    var Firm = mongoose.model('Firm');
    var firm, user, userPassword, createdFirm, loggedInUser;

    describe('GET /api/firms', function(){

    beforeEach(function (done) {

        firm = new Firm({ 
            company: 'My test company', 
            corporateMail: 'test.com' 
        });

        userPassword = 'password';
        user = new User({
            fistname: 'Fake User',
            lastname: 'Fake User',
            email: 'test@test.com',
            job: 'Partner',
            firmName:firm.company,
            password:userPassword,
            isActivated:true,
            _firmId:firm._id
        });   

        function createFirm(cb){
            request(app)
                .post('/api/firms')
                .send(firm)
                .expect(201)
                .end(function(err, res){
                    if ( err ) throw err;
                    createdFirm = res.body;
                    cb();
                });
        }

        function createUser(cb){
            request(app)
                .post('/api/common/users')
                .send(user)
                .expect(200)
                .end(function(err, res){
                    createdUser = res.body;
                    if ( err ) throw err;
                    cb();
                });
        };

        async.series([function(cb){
            createFirm(cb);
        }, function(cb){
            createUser(cb);
        }], done);    

    });


    afterEach(function (done) {
        firm.remove();
        user.remove();
        done();
    });

    it('should respond with 401 error', function(done) {
        request(app)
          .get('/api/firms')
          .expect(401)
          .end(function(err, res) {
            if (err) return done(err);
            done();
          });
    });

    it('should login', function(done) {
        request(app)
          .post('/auth/local')
          .send({email:user.email, password:user.password})
          .expect(200)
          .end(function(err, res) {
            if (err) return done(err);
            done();
          });
    });

    it('should respond with 200 after login', function(done) {
        request(app)
          .get('/api/firms')
          .expect(200)
          .end(function(err, res) {
            if (err) return done(err);
            done();
          });
    });

});

在工作流程中首先创建firm对象,然后返回其ID,以便我可以创建以firmId作为参考的用户。

我想在用户通过身份验证后测试/ api / firm路由,但是尽管我尝试了各种各样的尝试(使用superagent,登录before部分),我总是在上一次获得401响应{ {1}}部分而不是预期的200。

2 个答案:

答案 0 :(得分:1)

实际上,要记住的重要一点是,正如KJ3所说,如何设置身份验证。在我的情况下,我忘了提到我正在使用jwt。它的工作方式如下,您提供用户名和密码,服务器返回使用jwt创建的令牌。

因此,在测试中为每个请求发回令牌是有意义的。

实现此目的的方法首先是通过在前一节

中进行身份验证后存储令牌
    it('should respond with 200', function(done) {
        var authToken = 'Bearer ' + createdUser.token;
        request(app)
          .get('/api/firms')
          .set('Authorization', authToken)
          .expect(200)
          .end(function(err, res) {
            if (err) return done(err);
            done();
          });
    });

然后在请求中添加.set,并使用正确格式的令牌('承载' +令牌,在身份验证服务中定义):

netstat -aon | findstr 0.0:<your port number which is giving bind exception>

如果测试发回200,这是预期的,如果.set(...)被注释掉则发送401.

好消息是,这是通过supertest实现的,因此无需添加任何内容,不太好的消息是您需要将.set(...)添加到每个测试请求。

答案 1 :(得分:0)

如果你要在浏览器中完成最后两次测试,取决于你如何设置它,是的,它会因cookie和会话而起作用,但这里/ api / firm测试独立于auth / local测试。所以401是正确的反应。

这实际上取决于您的身份验证设置方式,但您还需要对/ api / firm测试进行身份验证。通过再次发送凭证(每次我的mocha测试中的每一个都进行身份验证)或者在测试中实现会话,请参阅this SO post以获取某些方向。