2

在使用 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。

4

1 回答 1

1

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

这是因为function run()a.jsfunction doStuff(data)中,闭包内的调用保留了a.jsfunction run()的内容,而不是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)insidefoo指向var a闭包内部foo的内容保留了a.js的内容。

Diana记录到控制台是因为console.log(this.b)insidefoo指向one.ba.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}`;
    }
})()
于 2016-11-29T11:45:39.130 回答