在sinon测试用例中无法在reject内传递参数

时间:2017-11-30 12:29:04

标签: node.js mocha sinon chai

这是我尝试使用sinon,chai,mocha进行测试的node.js代码。 我怎么不理解为什么我无法在拒绝sinon中传递参数。我尝试寻找在线帮助以及文档,但仍无法得到合适的理由。以下是我要测试的代码:

this.retrieveSomething =  function () {
  var promiseFunc = function (resolve, reject) { 
    Repository.findSomething( {$or: [{"status":"x"},{"status":"y"}]}, 'name description status')
      .then(function (result) {
        resolve(result);
      })
      .catch(function (err) {
        reject(new errors.InternalServerError('Failed to find Surveys',
          {errors: [{message: 'Failed  '}, {details: err.errors}]}));
      });
  };

  return new Promise(promiseFunc);
};

这是测试代码

it('failure', function (done) {
  var findSomethingStub = sinon.stub(Repository, 'findSomething');
  findSomethingStub.returnsPromise().rejects();

  var promise = fixture.retrieveSurveysVast();
  setTimeout(function () {
    expect(findSomethingStub.calledOnce).to.be.true;
    expect(promise).to.be.eventually.deep.equal("failed");
    Repository.findSomething.restore();
    done();
  }, 5);
});

此案例成功通过。然而,如果我试图以这种方式拒绝它,这就很奇怪了

findSomethingStub.returnsPromise().rejects("failed");

并像这样匹配

expect(promise).to.be.eventually.deep.equal("failed");

它说

Unhandled rejection InternalServerError: Failed to find Surveys 
事实上,我给予的内容并不重要。请帮助我为什么我无法传递参数拒绝并期望它等于相同的论点。

1 个答案:

答案 0 :(得分:1)

我希望我的回答很有用。 查看您的测试脚本..首先,您将Repository.findSomething存根以返回被拒绝的保证,其中包含字符串'failed'。因此,在实际的this.retrieveSomething代码中,它将落入catch语句:

.catch(function (err) {
        reject(new errors.InternalServerError('Failed to find Surveys',
          {errors: [{message: 'Failed  '}, {details: err.errors}]}));
      });

这意味着,(错误)将包含字符串'failed'作为被拒绝的承诺的结果。之后,this.retrieveSomething将返回promise reject,但它的值将由函数error.InternalServerError处理,该函数带有如上所述的2个参数。因此,函数this.retrieveSomething的被拒绝值取决于您error.InternalServerError的实现。

另外需要注意的是,我认为被拒绝的存根findSomethingStub.returnsPromise().rejects("failed");不会产生任何影响,因为error.InternalServerError会抓取err.errors,所以至少它应该是这样的:findSomethingStub.returnsPromise().rejects({errors: "failed"});

我试图通过假设来模拟你的代码.internalServerError返回一个这样的字符串:

class Errors {
    InternalServerError(string, obj) {
        return `error: ${string}, message: ${obj.errors[0].message}, details: ${obj.errors[1].details}`;
    } }

然后,在测试用例中我尝试

const fixture = require('../47573532-sinon-react/Fixture');
const Repository = require('../47573532-sinon-react/Repository');
const chai = require('chai');
const sinon = require('sinon');
const sinonChai = require('sinon-chai');
const chaiAsPromised = require('chai-as-promised');
const sinonStubPromise = require('sinon-stub-promise');

sinonStubPromise(sinon);
chai.use(chaiAsPromised);
chai.use(sinonChai);
chai.should();

describe('/47573532-sinon-react', () => {
    it('failure (using sinon, chai, sinon-stub-promise, chai-as-promised)', (done) => {
        const findSomethingStub = sinon.stub(Repository, 'findSomething');
        findSomethingStub.returnsPromise().rejects({ errors: 'failed' });
        const promise = fixture.retrieveSurveysVast();

        promise.should.be.rejected.then((err) => {
            err.should.be.deep.equal
            (
                'error: Failed to find Surveys, message: Failed  , details: failed'
            );
            findSomethingStub.restore();
        }).should.notify(done);
    });
});

首先,它将断言promise.should.be.rejected,然后根据InternalServerError实现结果评估错误。在这种情况下,我们需要确保details: 'failed'与存根拒绝的内容相匹配。如果我们用其他内容更改details值,则测试将失败。

it('failure (using sinon, chai, sinon-stub-promise, chai-as-promised)', (done) => {
        const findSomethingStub = sinon.stub(Repository, 'findSomething');
        findSomethingStub.returnsPromise().rejects({ errors: 'failed' });
        const promise = fixture.retrieveSurveysVast();

        promise.should.be.rejected.then((err) => {
            err.should.be.deep.equal
            (
                'error: Failed to find Surveys, message: Failed  , details: something not from stub'
            ); // this will cause test failed
            findSomethingStub.restore();
        }).should.notify(done);
    });