在 NodeJS 的匿名导出中使用 rewire 存根函数
Use rewire to stub function in anonymous export in NodeJS
**更新。根据下面的评论,用例可能不清楚。
为了扩展,在我的应用程序模块 foo() 中调用 bar() 执行一些复杂的逻辑和 returns 一个布尔值。我正在创建单元测试 (Mocha) 并尝试使用 rewire
重新连接 foo() 方法,这样我就可以将 true/false 传回 bar() 而无需实际调用 bar。
尝试在匿名函数中对 bar() 方法进行存根(又名重新连接)。可能吗?在尝试了很多不同的方法后,我看不出如何覆盖 bar()。
//foobar.js
module.exports = function(config) {
function bar() {
console.log('why am i in _%s_ bar?', config)
//some logic
return true
}
function foo() {
if (bar()) {
console.log('should not get here, but someVar is passing: ', someVar)
return true
} else {
console.log('should get here, though, and we still see someVar: ', someVar)
return false
}
}
return {
foo: foo,
bar: bar
}
}
和
//rewire_foobar.js
var rewire = require('rewire')
var myModule = rewire(__dirname + '/foobar.js')
myModule.__with__({
'bar': function(){
console.log('changing return to false from rewire')
return false
},
'someVar': "abcde"
})(function() {
var result = myModule('a').foo()
console.log('result is: ', result)
})
给出结果
why am i in _a_ bar?
should not get here, but someVar is passing: abcde
result is: true
someVar
正在通过。但是我需要重新连接 bar() ,这样它里面的逻辑就不会被调用。
我找到了解决方法。我最初的 objective 是测试 foo() 和存根 bar() 以便我可以控制 results/testing 参数。如果有人能提出更好的解决方案,那就太好了。
在这种方法中,每个变量和函数调用都需要 stubbed/rewired。这对我的测试没问题,但可能不适用于所有解决方案。
我的解决方法是:
将 foo() 函数写入临时文件。 (在测试中,这
should/could 在 before() 块中完成。
将函数作为独立函数进行测试。
删除测试临时文件。
这是 foobar.spec.js 的代码:
var rewire = require('rewire')
var foobar = require('./foobar.js')
var fs = require('fs')
//extracts the function to test and exports it as temp()
//could be done in a before() block for testing
var completeHack = 'exports.temp = ' + foobar().foo.toString()
//write the function to a temporary file
fs.writeFileSync(__dirname + '/temp.js', completeHack , 'utf8')
//rewire the extracted function
var myModule = rewire(__dirname + '/temp.js')
myModule.__with__({
//and stub/rewire and variables
'bar': function(){
console.log('changing return to false from rewire')
return false
},
'someVar': "abcde",
'config': 'not really important'
})(function() {
//and test for our result
var result = myModule.temp()
console.log('result is: ', result)
})
//and finally delete the temp file. Should be put in afterEach() testing function
fs.unlinkSync(__dirname + '/temp.js')
**更新。根据下面的评论,用例可能不清楚。
为了扩展,在我的应用程序模块 foo() 中调用 bar() 执行一些复杂的逻辑和 returns 一个布尔值。我正在创建单元测试 (Mocha) 并尝试使用 rewire
重新连接 foo() 方法,这样我就可以将 true/false 传回 bar() 而无需实际调用 bar。
尝试在匿名函数中对 bar() 方法进行存根(又名重新连接)。可能吗?在尝试了很多不同的方法后,我看不出如何覆盖 bar()。
//foobar.js
module.exports = function(config) {
function bar() {
console.log('why am i in _%s_ bar?', config)
//some logic
return true
}
function foo() {
if (bar()) {
console.log('should not get here, but someVar is passing: ', someVar)
return true
} else {
console.log('should get here, though, and we still see someVar: ', someVar)
return false
}
}
return {
foo: foo,
bar: bar
}
}
和
//rewire_foobar.js
var rewire = require('rewire')
var myModule = rewire(__dirname + '/foobar.js')
myModule.__with__({
'bar': function(){
console.log('changing return to false from rewire')
return false
},
'someVar': "abcde"
})(function() {
var result = myModule('a').foo()
console.log('result is: ', result)
})
给出结果
why am i in _a_ bar?
should not get here, but someVar is passing: abcde
result is: true
someVar
正在通过。但是我需要重新连接 bar() ,这样它里面的逻辑就不会被调用。
我找到了解决方法。我最初的 objective 是测试 foo() 和存根 bar() 以便我可以控制 results/testing 参数。如果有人能提出更好的解决方案,那就太好了。
在这种方法中,每个变量和函数调用都需要 stubbed/rewired。这对我的测试没问题,但可能不适用于所有解决方案。
我的解决方法是:
将 foo() 函数写入临时文件。 (在测试中,这 should/could 在 before() 块中完成。
将函数作为独立函数进行测试。
删除测试临时文件。
这是 foobar.spec.js 的代码:
var rewire = require('rewire')
var foobar = require('./foobar.js')
var fs = require('fs')
//extracts the function to test and exports it as temp()
//could be done in a before() block for testing
var completeHack = 'exports.temp = ' + foobar().foo.toString()
//write the function to a temporary file
fs.writeFileSync(__dirname + '/temp.js', completeHack , 'utf8')
//rewire the extracted function
var myModule = rewire(__dirname + '/temp.js')
myModule.__with__({
//and stub/rewire and variables
'bar': function(){
console.log('changing return to false from rewire')
return false
},
'someVar': "abcde",
'config': 'not really important'
})(function() {
//and test for our result
var result = myModule.temp()
console.log('result is: ', result)
})
//and finally delete the temp file. Should be put in afterEach() testing function
fs.unlinkSync(__dirname + '/temp.js')