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

时间:2017-02-09 11:24:57

标签: javascript function mocking mocha sinon

让我说我有一个功能

Func a() {
    //Do Something
    let c = b();
    return c;
}

我想测试函数a和mock b(),并且在mock中想要分配c。 Sinon.Stub(测试" B&#34)的回报。(" DummyValue&#34); c应该被赋予DummyValue。

我该怎么做?

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

3 个答案:

答案 0 :(得分:1)

当我们在同一个文件中有2个函数并希望将其中一个函数存根并测试另一个函数时。 例如,: 测试: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);

参考:Stubbing method in same file using Sinon

答案 1 :(得分:0)

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

  

经验法则是:如果你不为某些人添加断言   特定的电话,不要嘲笑它。改为使用存根。

我们在测试中的断言不是针对功能的特定呼叫,即第一次或第三次呼叫,而是所有呼叫。

我们可以通过电话来解决这个问题,因为我们已经将存根编程为始终返回相同的结果,无论调用方式如何(参数或调用次数)。

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

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

    return c;
}

test.js

require("sinon")

describe("a", () => {
    const stub = sinon.stub();
    stub.returns("DummyValue");
    expect(a(stub)).to.eql.("DummyValue");
})

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

答案 2 :(得分:0)

您只能使用存根功能

  • 如果您将其作为参数传递,则使用sinon
  • 等测试双精度库假冒它
  • 或者它是依赖项(通过importrequire加载)。在这种情况下,您可以使用proxyquire为您正在测试的模块传递假b函数。函数本身可以由sinon或其他测试双精度库伪造。