useFakeTimers mocha chai sinon - 测试结果不正确

时间:2017-02-15 20:13:52

标签: mocha jwt sinon chai sinon-chai

我正在尝试运行测试,我想验证我的帮助文件是否正确运行,如果我有一个过期的令牌,我会收到错误回复,无法继续。

我有一种感觉,我只能在测试中直接伪造时间,而不是在测试之外。事实上,我不想在我的测试中复制jwt.verify函数,因为如果我改变实际帮助文件中的代码,那就失败了。有什么帮助使这个工作?

我假装与sinon在一起。如果我测试看看我现在的时间和时间滴答,我确实得到了正确的结果。但由于某种原因,这不适用于另一个文件中的函数。

我的 local.js 文件

const moment = require('moment');
const jwt = require('jsonwebtoken');

const secret = process.env.TOKEN_SECRET;

function encodeToken(user) {
  const playload = {
    exp: moment().add(1, 'hours').unix(), // expires the token in an hour
    iat: moment().unix(),
    sub: user.id
  };

  return jwt.sign(playload, secret);
}

function decodeToken(token, callback) {
  const payload = jwt.verify(token, secret, function (err, decoded) {
    const now = moment().unix();
    console.log('tim: ' + decoded.exp); //just to see
    console.log('now: ' + now); // just to see
    if (now > decoded.exp) {
      callback('Token has expired.');
    }
    callback(null, decoded);
  });
}

module.exports = {
  encodeToken,
  decodeToken
};

和我的测试文件

process.env.NODE_ENV = 'test';

const chai = require('chai');
const should = chai.should();
const sinon = require('sinon');

const localAuth = require('../../src/server/auth/local');

describe('decodeToken()', function () {
    var clock;
    beforeEach(function () {
      clock = sinon.useFakeTimers();
    });

    afterEach(function () {
      clock.restore();
    });
    it('should return a decoded payload', function (done) {
      const token = localAuth.encodeToken({
        id: 1
      });
      should.exist(token);
      token.should.be.a('string');
      clock.tick(36001000000);
      localAuth.decodeToken(token, (err, res) => {
        should.exist(err);
        res.should.eql('Token has expired.');
        done();
      });
    });
  });

1 个答案:

答案 0 :(得分:1)

JWT检查到期并自行抛出错误。所以我们只需要从错误消息中断言。我对代码进行了一些更改并使其正常工作。

我测试了如下,(代码片段)

const moment = require('moment');
const jwt = require('jsonwebtoken');

const secret = 'abczzxczxczxc';

function encodeToken(user) {
  const payload = {
    exp: moment().add(1, 'hours').unix(), // expires the token in an hour
    iat: moment().unix(),
    sub: user.id
  };

  const token = jwt.sign(payload, secret);
  return token;
}

function decodeToken(token, callback) {
  jwt.verify(token, secret, function(err, decoded) {
    callback(err, decoded);
  });
}

module.exports = {
  encodeToken,
  decodeToken
};

测试如下,

process.env.NODE_ENV = 'test';

const chai = require('chai');
const should = chai.should();
const sinon = require('sinon');

const localAuth = require('./');

describe('decodeToken()', function () {
  var clock;
  beforeEach(function () {
    clock = sinon.useFakeTimers();
  });

  afterEach(function () {
    clock.restore();
  });
  it('should return a decoded payload', function (done) {
    const token = localAuth.encodeToken({
      id: 1
    });
    token.should.exist;
    token.should.be.a('string');
    clock.tick(36001000000);
    localAuth.decodeToken(token, (err, res) => {
      should.exist(err);
      err.message.should.eql('jwt expired');
      done();
    });
  });
});

输出

  

➜futtitimer./node_modules/mocha/bin/mocha index_test.js

     

decodeToken()       ✓应返回已解码的有效载荷

     

1次传球(17ms)