如何存根从另一个函数调用的模块函数

时间:2019-07-06 10:45:25

标签: javascript node.js typescript sinon

我的module.ts文件具有2个功能:

export async function foo() {
    var barVal = await bar();
    doSomethingWithBarVal(barVal);
}

export async function bar(): Bar {
    return await somethingAsync();
}

在测试中,我想stub bar()并为mock返回Bar(返回值bar()

我当前的测试如下:

var module = require('module.ts');
var myStub = sinon.stub(module, 'bar').resolves(myMock);
await foo();
expect(myStub.calledOnce);

但是,expect总是失败,并且会调用'real'bar()
如果我直接从测试中调用bar(),那么存根被称为,但是我想测试整个流程。

1 个答案:

答案 0 :(得分:2)

您的方法存在的问题是您正在对模块对象进行存根(exports,因为您在测试中使用commonjs require),而您的foo函数使用了可用的bar在模块范围内。

要解决此问题,您可以在此处选择几个选项。

1。又快又脏

exports.bar中使用bar代替foo

export async function foo() {
    var barVal = await exports.bar();
    doSomethingWithBarVal(barVal);
}

这种方法实际上是一种利用您的模块将被转换为commonjs格式的事实的黑客。有朝一日可能不是真的,但现在可以使用。

2。拥抱ES模块的静态性质

拥抱ES模块是静态的事实。通过明确允许将bar指定为其参数,使函数“可再次测试”

export async function foo(_bar = bar) {
    var barVal = await _bar();
    doSomethingWithBarVal(barVal);
}

// test.js
await foo(mockBarImplementation)

3。进阶

使用一些IoC/DI实现。例如typescript-ioc