2016-07-29 11 views
2

スタブ/モック(外部APIを呼び出すため)を使用して単体テストしたいパスポート用のローカルログイン戦略の中にいくつかのロジックがありますが、テストする機能には入らないようですそれ。パスポートのローカル戦略をテストする方法は? (sinon、proxyquire)

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における機能のセットアップ:私の知る限り

​​

、passport.authenticate方法

は、ここに私のtest.jsファイルです呼び出されていません(常にfalseを返します)。私がproxyquireを削除して、パスポートを& config/passport.jsに '普通に'要求すると、応答もfalseになります。

これはちょっと複雑なので、これをテストする方法についての他の提案は非常に高く評価されます。

編集現在のコードを追加するには、次

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; 


    }); 

    }); 

を私は本当に簡単&ダム何かを見下ろすよかなり確信しているが、私は通常のcallbackyラッパーは、パスポートの構文で動作するように見えることはできません。認証する。 :(

答えて

1

のconfig/

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(); 
 
}); 
 
});

+0

をpassport.jsありがとうございました!これは*ほぼ*私のために働いています。 .. :) mockReqの 'logIn:function(){}'とは何ですか?そして、passport.authenticateから戻り値をテストするにはどうすればよいですか? (それはユーザーを返すことになっています) – esperluette

+0

これはパスポートによって注入されるパスポート機能です。 req.logInを削除すると失敗します。 –

+0

「どうすれば返された値をpassport.authenticateからテストできますか?」と説明してください。 –

関連する問題