Sinon 单元测试 'catch' 语句

Sinon to unit test 'catch' statement

我有一个简单的函数,例如;

module.exports = {
  fetchUser:function(myUserId) {
    return new Promise((resolve, reject) => {
      this.getUser(myUserId)
        .then(user => {
          // do logic // then return user

          return user;
        })
        .then(resolve)
        .catch(err => {
          // whoops there has been an error

          let error = { error: 'My Error' };

          reject(error);
        });
    });
  }
};

我想对 resolvereject 结果进行单元测试。

一个简单的 chai 测试是;

var expect = require('chai').expect;
var user = require('./user');

describe('User module', function() {
  it('test fetchUser', function() {
    let _user = user.fetchUser('abc123');

    return _user
      .then(user => {
        expect(data).to.be.an('object');
      });
  });

使用 sinon 或其他库,我如何让 fetchUser 函数抛出 reject 错误?

从 "logic" 中可能引发错误的任何内容开始。

如果不是,您需要存根 this.getUser 以拒绝或抛出错误而不是返回数据。 sinon-as-promised patches sinon.stub to include the .resolves and .rejects 承诺帮手。

const sinon  = require('sinon')
require('sinon-as-promised')

设置失败测试的存根。

before(function(){
  sinon.stub(user, 'getUser').rejects(new Error('whatever'))
})

after(function(){
  user.getUser.restore()
})

然后要么捕获 .fetchUser 错误,要么使用 chai-as-promised 来获取一些糖分。

it('test fetchUser', function() {
  return user.fetchUser('abc123')
    .then(()=> expect.fail('fetchUser should be rejected'))
    .catch(err => {
      expect(err.message).to.eql('whatever')
    })
})

it('test fetchUser', function() {
  return expect(user.fetchUser('abc123')).to.be.rejectedWith(Error)
})

async如果你生活在新世界

it('test fetchUser', async function() {
  try { 
    await user.fetchUser('abc123')
    expect.fail('fetchUser should be rejected'))
  } catch(err) {
    expect(err.message).to.eql('whatever')
  }
})

附带说明一下,您不需要将已经 returns 承诺的东西包装在 new Promise 中,并且在链接多个 .catch 处理程序时要小心丢失错误信息。

fetchUser: function (myUserId) {
  return this.getUser(myUserId)
    .then(user => {
      //logic
      return user
    })
    .catch(err => {
      let error = new Error('My Error')
      error.original = err
      reject(error)
    });
}

使用MochaChaiSinon可以用stubbed方法实现getUser

const User = require("./fetchUserModule");

describe('User module', () => {
    beforeEach(() => User.getUser = sinon.stub());

    afterEach(() => User.getUser.reset());

    it('returns user if `getUser` returns data', () => {
        const user = {name: 'John'};
        User.getUser.withArgs("abc123").returns(Promise.resolve(user));

        return User.fetchUser("abc123").then(result => {
            expect(result).to.equal(user)
        }).catch(error => {
            expect(error).to.be.undefined;
        })
    });

    it('throws error if `getUser` is rejected', () => {
        User.getUser.withArgs("abc123").returns(Promise.reject());

        return User.fetchUser("abc123").then(result => {
            expect(result).to.be.undefined;
        }).catch(err => {
            expect(err).to.eql({error: 'My Error'})
        })
    });
});