如何在使用导入时存根ES6 node_modules?

时间:2017-09-09 09:13:50

标签: javascript unit-testing import ecmascript-6 stub

编写测试时我有点困惑。我的筹码是mocha,chai和sinon + babel。最近我开始使用ES6导入和导出。它到目前为止工作得很好,但我在模拟一些依赖项时遇到了麻烦。这是我的情况:

service.js

import {v4} from 'uuid';

function doSomethingWithUuid() {
    return v4();
}

export function doSomething() {
    const newUuid = doSomethingWithUuid();
    return newUuid;
}

service.test.js

import {doSomething} from './service';

describe('service', () => {
    it('should doSomething' () => {
        // how to test the return of doSomething ? 
        // I need to stub v4 but I don't know how...
    });
});

我考虑过的事情:sinon.stub,但我还没有成功。尝试使用import * as uuid from 'uuid'导入所有uuid。但在我的service.js中,它仍然存在 原来的功能叫做...... 此外,由于导入应该是只读的,一旦它是原生的,这个解决方案就行不通了......

我在网上找到的唯一有趣的事情是这个解决方案,在我的服务中添加一个功能,以便让外界覆盖我的依赖。 (见https://railsware.com/blog/2017/01/10/mocking-es6-module-import-without-dependency-injection/)。

import * as originalUuid from 'uuid';

let {v4} = originalUuid;
export function mock(mockUuid) {
  ({v4} = mockUuid || originalUuid);
}

编写这个小样板代码是可以的,但是在我的代码中添加它会让我感到麻烦...我宁愿在我的测试或一些配置中编写样板文件。另外,我不想 有一个IoC容器,我希望尽可能少地保持我的功能并保持尽可能的功能......

你有什么想法吗? :)

1 个答案:

答案 0 :(得分:2)

您应该能够使用像proxyquire这样的模块。这不是经过测试的代码,但它将类似于以下内容:

const proxyquire = require('proxyquire');
const uuidStub = { };

const service = proxyquire('./service', { uuid: uuidStub });
uuidStub.v4 = () => 'a4ead786-95a2-11e7-843f-28cfe94b0175';

describe('service', () => {
  it('should doSomething' () => {
    // doSomething() should now return the hard-coded UUID
    // for predictable testing.
  });
});