我的本地登录策略中有一些逻辑用于护照我想用stubs / mocks进行单元测试(因为它调用外部API),但我似乎无法进入函数来测试它。
这是我的test.js文件:
var expect = require('chai').expect;
var sinon = require('sinon');
var proxyquire = require('proxyquire');
require('../config/passport.js');
describe('it should get user account from the API', function () {
it('should be able to access passport authenticate', function(){
var reqUserObject = {
body: { user_name: 'fakeymcfakeypants', password: '123Skidoo' }
}
var requestPromiseStub = sinon.stub();
requestPromiseStub.onCall(0).returns(Promise.resolve('{"userId": 138}'))
.onCall(1).returns(Promise.resolve('{"userName": "fakeymcfakeypants", "status": 0}'))
var passportTest = proxyquire('passport', {
'request-promise': requestPromiseStub
});
var passportStub = sinon.stub(passportTest, "authenticate");
var response = passportStub.calledWith('localLogin', reqUserObject);
console.log(response);
expect.response.to.be.true;
});
});
config / passport.js中的功能设置:
var rp = require('request-promise');
var passport = require("passport");
var LocalStrategy = require('passport-local').Strategy;
module.exports = function (passport, LocalStrategy) {
passport.use('localLogin', new LocalStrategy({
usernameField : 'user[user_name]',
passwordField : 'user[password]'},
function(username, password, done) {
//logic blah blah blah here, uses two request-promise calls
return done(null, username);
})
)
}
据我所知,没有调用passport.authenticate方法(它总是返回false)。如果我删除proxyquire并且只需要护照& config / passport.js'通常'反应也是错误的。
我知道这有点复杂,所以关于如何测试这个的任何其他建议将不胜感激!
编辑添加当前代码:
var expect = require('chai').expect;
var chai = require('chai');
var sinon = require('sinon');
var proxyquire = require('proxyquire');
var passport = require('passport');
var sinonChai = require('sinon-chai');
var async = require('async');
chai.use(sinonChai);
describe('canary test: passport', function (){
it('should pass this canary test', function(){
expect(true).to.be.true;
});
});
describe('it should get user account from the API', function () {
var authSpy;
var requestPromiseStub;
var passportResponse;
var userResponse;
beforeEach(function () {
this.sandbox = sinon.sandbox.create()
authSpy = sinon.spy(passport, 'authenticate');
})
afterEach(function () {
this.sandbox.restore()
})
it('should be able to access passport authenticate', function(){
var mockReq = {
body: {
username: 'fakeymcfakeypants',
password: '123Skidoo'
},
logIn: function () {}
};
var mockRes = {
};
requestPromiseStub = sinon.stub();
next = sinon.stub();
requestPromiseStub.onCall(0).returns(Promise.resolve({userId: 138, statusCode: 200}))
.onCall(1).returns(Promise.resolve({userName: 'fakeymcfakeypants', status : 0}))
var overrides = {
'request-promise': requestPromiseStub,
'authenticate': {authenticate: authSpy}
};
proxyquire('../config/passport.js', overrides)();
//added 'next' here as authenticate expects it: https://github.com/jaredhanson/passport/blob/master/lib/middleware/authenticate.js#L81
//passport should return either a username, or false, not sure how to access that?
passport.authenticate('localLogin')(mockReq, mockRes, next);
// if I comment out the 'logIn' function above and make an explicit function here I can see the username being returned, but of course it's inside the function closure:
passport.authenticate('localLogin', function(err, user){
// I can see here that the username is correct:
console.log(user)
})(mockReq, mockRes, next);
expect(requestPromiseStub).to.have.been.called;
});
});
我很确定我忽略了一些非常简单的事情。愚蠢,但我似乎无法使用passport.authenticate的语法来获得正常的回调包装。 :(
答案 0 :(得分:2)
配置/ passport.js
var rp = require('request-promise');
var passport = require('passport');
var LocalStrategy = require('passport-local').Strategy;
module.exports = function () {
passport.use('local', new LocalStrategy({
usernameField: 'username',
passwordField: 'password'
},
function (username, password, done) {
console.log('logic blah blah blah here, uses two request-promise calls');
return done(null, username);
}));
};

test.js
var chai = require('chai');
var expect = require('chai').expect;
var sinon = require('sinon');
var proxyquire = require('proxyquire');
var passport = require('passport');
var sinonChai = require('sinon-chai');
chai.use(sinonChai);
describe('it should get user account from the API', function () {
it('should be able to access passport authenticate', function () {
// configure request and response
var mockReq = {
body: {
username: 'johndoe',
password: 'secret'
},
logIn: function () {}
};
var mockRes = {};
// configure request-promise
var requestPromiseStub = sinon.stub();
requestPromiseStub
.onCall(0).returns(Promise.resolve({
userId: 138
}))
.onCall(1).returns(Promise.resolve({
userName: 'johndoe',
status: 0
}));
var overrides = {
'request-promise': requestPromiseStub
};
proxyquire('./passport.js', overrides)();
passport.authenticate('local')(mockReq, mockRes);
// ASSERTS HERE
//expect(requestPromiseStub).to.have.been.called();
});
});