存根和代理

时间:2016-11-29 01:02:27

标签: javascript testing sinon proxyquire

在使用proxyquire之后,我遇到了使用sinon对特定函数进行存根的问题。

示例:

// a.js
const api = require('api');

module.exports = (function () {
    return {
        run,
        doStuff
    };

    function run() {
        return api()
            .then((data) => {
                return doStuff(data);
            })
    }

    function doStuff(data) {
        return `Got data: ${data}`;
    }
})()

// a.spec.js - in the test
a = proxyquire('./a', {
    'api': () => Promise.resolve('data')
})
sinon.stub(a, 'doStuff');
// RUN TEST - call a.run()

我知道它不起作用,因为它调用原始的doStuff而不是模拟/存根的doStuff。

1 个答案:

答案 0 :(得分:1)

  

我知道它不起作用,因为它会调用原来的doStuff   一个模拟/存根的doStuff。

这是因为 a.js 中的function run()调用function doStuff(data)内的function run()隐藏了 a.js的内容 a_spec.js 而不是function doStuff(data)

以示例说明

让我们将a.js重写为:

var a = 'I am exported';
var b = 'I am not exported';

function foo () {
    console.log(a);
    console.log(this.b)
}

module.exports.a=a;
module.exports.foo=foo;

和a.spec.js到:

var one = require('./one');

console.log(one); // { a: 'I am exported', foo: [Function: foo] }

one.a = 'Charles';
one.b = 'Diana';

console.log(one); // { a: 'Charles', foo: [Function: foo], b: 'Diana' }

现在,如果我们调用one.foo(),它将导致:

I am exported
Diana

I am exported已记录到控制台,因为console.log(a)内的foo指向var a内的foo内的Diana内容 a.js

console.log(this.b)已记录到控制台,因为foo中的one.b指向 a.spec.js 中的module.exports = (function () { return { run, doStuff }; function run() { return api() .then((data) => { return doStuff(data); }) } function doStuff(data) { return `Got data: ${data}`; } })()

那么你需要做些什么才能使它发挥作用?

您需要更改:

module.exports = (function () {
    return {
        run,
        doStuff
    };

    function run() {
        return api()
            .then((data) => {
                return this.doStuff(data); // ´this.doStuff´ points to ´doStuff´ in the exported object
            }.bind(this)) // to ensure that ´this´ does not point to the global object
    }

    function doStuff(data) {
        return `Got data: ${data}`;
    }
})()

为:

sqlcmd -S GT044 -E -i backup.sql