Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/418.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript undefined不是函数:单元测试passport身份验证自定义回调_Javascript_Node.js_Unit Testing_Express_Passport.js - Fatal编程技术网

Javascript undefined不是函数:单元测试passport身份验证自定义回调

Javascript undefined不是函数:单元测试passport身份验证自定义回调,javascript,node.js,unit-testing,express,passport.js,Javascript,Node.js,Unit Testing,Express,Passport.js,我是passport和express的新手,试图通过为所有代码创建单元测试来更好地了解所有东西是如何协同工作的。我一直很成功,但今天遇到了一个我不太明白的问题 我正在尝试对session.js上导出的以下函数进行单元测试: 我似乎对倒数第二行req、res、next以及如何/何时调用都有问题。我还从未在Javascript中见过这种类型的调用,其中最后一行只是一组参数 为了测试我使用的是,西农和摩卡。在我的测试中,我使用rewire将passport依赖项更改为我控制的模拟对象 我的测试似乎按预

我是passport和express的新手,试图通过为所有代码创建单元测试来更好地了解所有东西是如何协同工作的。我一直很成功,但今天遇到了一个我不太明白的问题

我正在尝试对session.js上导出的以下函数进行单元测试:

我似乎对倒数第二行req、res、next以及如何/何时调用都有问题。我还从未在Javascript中见过这种类型的调用,其中最后一行只是一组参数

为了测试我使用的是,西农和摩卡。在我的测试中,我使用rewire将passport依赖项更改为我控制的模拟对象

我的测试似乎按预期运行,从失败的地方和instanbul告诉我的内容可以看出这一点,但它总是抛出:TypeError:undefined不是一个函数

如果我注释掉session.js中的req,res,下一行,那么我的测试实际上成功运行

My test session.unit.js:

我的问题是:

最后一行req,res,下一个用于什么,何时调用?我怀疑中间件 有没有一种方法可以让我的测试在没有未定义错误的情况下通过? 非常感谢您的阅读和任何帮助

**编辑:** 我想我漏掉了一条重要的信息。。。这个session.login函数是从我的routes.js文件中调用的,因此我认为中间件需要最后一行才能继续。但是,我仍然不知道如何让它在单元测试中继续处理

routes.js代码段:

**编辑2:**

添加了session.js的顶部,以清楚说明最初如何使用require声明passport。在单元测试中,我使用模拟存根对象通过重新布线替换passport,以便控制passport返回的内容

}req,res,next;在会话即将结束时,由于作用域规则在JavaScript中的工作方式以及passport.authenticate不返回函数,它可能不会返回任何默认情况下返回未定义的函数,因此没有必要使用.js,这就是错误的原因

只需更改}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();

谢谢你的回答!我试图通过删除该行来更新代码,但在等待/api/session返回时,我的e2e测试开始失败。我用相关的routes.js代码片段更新了上面的问题,如果有什么变化,请告诉我。谢谢我看不出您在哪里定义passport变量。你的密码需要护照。如果没有定义,你会得到准确的错误。还要检查中间件的顺序。Passport应该在会话之后,因为它将req.logIn和其他内容注入到您的会话中。Biba,谢谢您的关注。我添加了一些可能与我原来的问题不符的陈述。我正在使用rewire注入一个模拟passport对象并存根它的返回调用。中间件的顺序不应该影响这一点,因为这是一个测试,尽管我可能会弄错。但我不知道您在哪里声明了本地身份验证策略。您正在调用authenticate,但我根本看不到声明的策略。作为错误的基准,它表示您正在调用一个null对象的方法,这意味着一些未定义或该方法不存在的东西,通常表示注入没有发生,passport没有看到定义要将自身注入的express会话。嗨,Biba,这实际上是我的意图。我正在尝试用我自己的存根完全替换passport.authenticate呼叫。我在测试中的语句:passportMock.authenticate=sinon.stub.callsArgWith1,‘ERROR’,null,null;正在告诉我的被测类调用带有“ERROR”的身份验证回调arg 1,以便我可以模拟身份验证异常。Stephenmuss,感谢您的帮助,这基本上成功了。关键是存根需要返回一些东西,而我没有这样做,我只是调用回调。我的最后一行是:passportMock.authenticate=sinon.stub.callsArgWith1,null,null,'INFO'。returnsfunction{};这允许按预期调用回调,同时根据中间件要求返回空函数。再次感谢你的帮助!
'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;
    });

  });

});
  app.route('/api/session')
    .post(session.login)
    .delete(session.logout);
var stub = sinon.stub(passport, 'authenticate').returns(function() {});
stub.yields(new Error('fails here'));

// add your tests here

stub.restore();