如何使用Sinon.JS模拟回调内的模块函数?

时间:2016-11-17 13:38:18

标签: javascript unit-testing promise sinon stub

我有以下Javascript代码:

import Notifications from 'notification-system';

export class DocumentParameters {
  handleUpload() {
    return Promise.resolve().then(() => {
      Notifications.success();
    });
  }
}

notification-system是我用npm安装的模块。

我想在此单元测试中模拟Notifications.success

import Notifications from 'notification-system';
import { expect } from 'chai';
import sinon from 'sinon';
import { DocumentParameters } from './document';

describe('handleUpload()', () => {
  it('should upload and create a success notification', (done) => {
    const success = sinon.stub(Notifications, 'success');
    const documentParameters = new DocumentParameters();

    documentParameters.handleUpload().then(() => {
      expect(success.callCount).to.equal(1);
      done();
    });

    success.restore();
  });
});

此单元测试失败,因为永远不会调用存根:success.callCount为0。

我的解决方案:

import Notifications from 'notification-system';

export class DocumentParameters {
  handleUpload() {
    const success = Notifications.success;
    return Promise.resolve().then(() => {
      success();
    });
  }
}

因此存根在回调之外工作但不在内部。但是,我被告知更新原始代码以进行工作单元测试是不好的做法。

您是否知道一个并不意味着更改原始代码的解决方案?

1 个答案:

答案 0 :(得分:0)

因为有人提出了我的问题:

这里的问题是我过快地恢复了存根success。 存根应该在promise .then()中恢复。

以下代码可行:

import Notifications from 'notification-system';
import { expect } from 'chai';
import sinon from 'sinon';
import { DocumentParameters } from './document';

describe('handleUpload()', () => {
  it('should upload and create a success notification', (done) => {
    const success = sinon.stub(Notifications, 'success');
    const documentParameters = new DocumentParameters();

    documentParameters.handleUpload().then(() => {
      expect(success.callCount).to.equal(1);
      success.restore();
      done();
    });
  });
});