Javascript 如何使用sinon在另一个函数(我正在测试)中模拟函数?

Javascript 如何使用sinon在另一个函数(我正在测试)中模拟函数?,javascript,function,mocking,mocha.js,sinon,Javascript,Function,Mocking,Mocha.js,Sinon,假设我有一个函数 Func a() { //Do Something let c = b(); return c; } 我想测试函数a和mock b(),并在mock中指定c。 Sinon.存根(测试,“b”).返回(“DummyValue”); 应为c指定DummyValue 我该怎么做 describe("a", () => { let a = a(); //mock b(); action = execute(a); expe

假设我有一个函数

Func a() {
    //Do Something
    let c = b();
    return c;
}
我想测试函数a和mock b(),并在mock中指定c。 Sinon.存根(测试,“b”).返回(“DummyValue”); 应为c指定DummyValue

我该怎么做

describe("a", () => {
    let a = a();
    //mock b();
    action = execute(a);
    expect(action).should.return.("DummyValue");
})

在这种情况下,sinon存根比模拟存根更合适 何时使用模拟与存根?

经验法则是:如果您不为某些 具体的要求,不要嘲笑它。改用存根

我们在测试中的断言不是针对函数a的特定调用,即第一次或第三次调用,而是针对所有调用

我们可以这样做,因为我们已经将存根编程为始终返回相同的结果,而不管调用它的方式(参数或调用次数)

将sinon存根函数作为参数传递给函数a。

Function a(b) {
    const c = b();

    return c;
}
test.js

const ser = require('./foo');
const sinon = require('sinon');

const aStub = sinon.stub(ser, 'a').returns('mocked return');
console.log(ser.b());
console.log(aStub.callCount);

请注意,我们可以对这些变量声明使用const,因为它们永远不会被重新分配。

您只能使用存根函数

  • 如果您将其作为参数传递,并使用test double库(如
    sinon
  • 或者如果它是依赖项(通过
    导入
    要求
    加载)。在这种情况下,您可以使用
    proxyquire
    通过测试模块的伪
    b
    功能。函数本身可以被
    sinon
    或其他测试双重库伪造

当我们在同一个文件中有两个函数,并且想要存根其中一个并测试另一个时。 例如,: 测试:tests.js

let ComputeSumStub = sinon.stub(OfflineLoader, "ComputeSum");
const ans = function ()
{
    return 10;
};
ComputeSumStub.returns(ans);
const actualValue: number = OfflineLoader.sum();
expect(actualValue).to.be.equal(10);
Dev:foo.js

function sum(): number
{
    return ComputeSum(8, 9);
}

function ComputeSum(a: number, b: number): number
{
    return a + b;
}
我们无法做到这一点,因为编译后,函数以不同的签名导出,使用全名,在存根时,我们存根全局函数,但在从另一个函数中调用它时,我们调用局部函数,因此它不起作用。 有一个解决方法可以做到这一点

foo.js
const factory = {
  a,
  b,
}
function a() {
  return 2;
}

function b() {
  return factory.a();
}

module.exports = factory;
test.js

const ser = require('./foo');
const sinon = require('sinon');

const aStub = sinon.stub(ser, 'a').returns('mocked return');
console.log(ser.b());
console.log(aStub.callCount);

Ref:

我不想将函数/存根作为参数传递。我想在不传递函数b的情况下实现这一点。可能吗?这是可能的,但不推荐通过像重新布线库这样的东西。Monkey patching是在运行时修改模块或包以改变执行过程的艺术。因此,你将是猴子修补。我相信我的方法比安装外部模块在运行时改变执行更简单。