簡體   English   中英

undefined不是函數:單元測試護照身份驗證自定義回調

[英]undefined is not a function: unit testing passport authentication custom callback

我剛接觸護照並表達意見,並試圖通過為我的所有代碼創建單元測試來更好地了解一切如何協同工作。 我一直都取得成功,但今天遇到了一個我不太了解的問題...

我正在嘗試對session.js上的以下導出功能進行單元測試:

'use strict';

var mongoose = require('mongoose'),
passport = require('passport');

exports.login = function (req, res, next) {
  passport.authenticate('local', function(err, user, info) {
    var error = err || info;
    if (error) return res.json(401, error);

    req.logIn(user, function(err) {

      if (err) return res.send(err);
      res.json(req.user.userInfo);
    });
  })(req, res, next);
};

我似乎在倒數第二行(req,res,next)以及如何/何時調用它方面遇到麻煩。 我也從未在Javascript中看到過這種類型的調用,其中最后一行只是一組參數。

為了測試我使用的是重新布線 ,興農,和摩卡。 在我的測試中,我使用重接線將護照依賴關系更改為我控制的模擬對象。

我的測試似乎在按預期方式工作,如失敗的地方以及instanbul告訴我的內容所涵蓋,但它總是拋出: TypeError: undefined is not a function

如果我注釋掉session.js(req,res,next)行,則我的測試實際上可以成功運行。

我的測試session.unit.js

'use strict';

var rewire = require('rewire'),
should = require('should'),
sinon = require('sinon'),
sessionController = rewire('../../../../lib/controllers/session'),
passportMock = {};


describe('Session Controller', function() {

  describe('#login', function(){

    beforeEach(function(){
      sessionController.__set__({
        'passport': passportMock
      });

    });

    it('should return 401 status and error if passport authentication returns error', function(){
      //given
      var res = {
          json: sinon.spy(),
          send: sinon.spy()
        },
        req = {
          logIn: sinon.spy()
        },
        next = sinon.stub();

      passportMock.authenticate = sinon.stub().callsArgWith(1, 'ERROR', null, null);

      //when
      sessionController.login(req, res, next);

      //then
      res.json.calledWith(401,'ERROR').should.be.true;
    });

  });

});

我的問題是:

  1. 最后一行是什么(req,res,next),何時調用? (我懷疑中間件)
  2. 有沒有一種方法可以更改測試以使其通過且不會出現未定義的錯誤?

非常感謝您的閱讀和提供的任何幫助!!

** 編輯: **我認為我遺漏了重要的信息...從我的routes.js文件中調用了session.login函數,因此我認為中間件繼續需要最后一行。 我仍然對如何讓它在單元測試中繼續進行處理感到困惑。

routes.js代碼段:

  app.route('/api/session')
    .post(session.login)
    .delete(session.logout);

**編輯2 **

添加了session.js的頂部,以清楚說明最初如何使用require聲明護照。 在單元測試中,我通過用模擬(存根)對象通過重接線替換護照,以便可以控制護照返回的內容。

  1. })(req, res, next); 由於JavaScript中的作用域規則是如何工作的,並且因為passport.authenticate不會返回函數(它可能不返回任何東西,默認情況下未返回未定義的函數),因此沒有必要在session.js的末尾進行操作,因此這就是錯誤的原因。

  2. 只需更改})(req, res, next); 從session.js的末尾到});

我不確定這是否會有所幫助,但這通常是我以與您相同的方式使用時存根passport.authenticate的方式。

var stub = sinon.stub(passport, 'authenticate').returns(function() {});
stub.yields(new Error('fails here'));

// add your tests here

stub.restore();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM