存根和代理
Stubs and proxquire
我在使用 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 而不是 mocked/stubbed doStuff。
I know it isn't working because it calls the original doStuff instead
of a mocked/stubbed 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
被记录到控制台,因为 foo
内的 console.log(a)
指向闭包内的 var a
foo
保留了 a.js.
Diana
被记录到控制台,因为 foo
中的 console.log(this.b)
指向 a.spec.js[=55= 中的 one.b
].
那么你需要做什么才能让它发挥作用?
您需要更改:
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}`;
}
})()
我在使用 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 而不是 mocked/stubbed doStuff。
I know it isn't working because it calls the original doStuff instead of a mocked/stubbed 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
被记录到控制台,因为 foo
内的 console.log(a)
指向闭包内的 var a
foo
保留了 a.js.
Diana
被记录到控制台,因为 foo
中的 console.log(this.b)
指向 a.spec.js[=55= 中的 one.b
].
那么你需要做什么才能让它发挥作用?
您需要更改:
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}`;
}
})()