我目前正在试验https://github.com/felixge/node-sandboxed-module能够在单元测试中注入依赖性模拟。原来这个模块杀死了在沙盒模块中创建的对象的should.js:
myModule.js:
module.exports = {
func1: function () {
return {
'THIS': {
'IS': {
'SPARTA': {
'DONT': 'TRUST ME'
}
}
}
};
}
};
Mymodule中-test.js:
var should = require('should');
var sandboxedModule = require('sandboxed-module');
var myModule1 = require('./myModule');
var myModule2 = sandboxedModule.require('./myModule');
describe('myModule', function () {
it('should return the object', function () {
myModule1.func1().should.be.instanceOf(Object);
});
describe('returned object', function () {
it('should have the correct properties', function () {
myModule1.func1().THIS.should.have.property('IS');
});
});
});
describe('Sandboxed myModule', function () {
describe('returned object', function () {
it('should have the should property', function () {
should.exist(myModule2.func1().should);
});
describe('nested objects', function () {
it('should have the should property', function () {
should.exist(myModule2.func1().THIS.should);
should.exist(myModule2.func1().THIS.IS.should);
});
});
});
});
有关沙盒模块的这些测试失败:
1) Sandboxed myModule returned object should have the should property:
AssertionError: expected undefined to exist
2) Sandboxed myModule returned object nested objects should have the should property:
AssertionError: expected undefined to exist
我尝试提供Object构造函数以确保原型中的隐藏属性是否可用,但这也不起作用:
var myModule2 = sandboxedModule.require('./myModule', {
globals: {
Object: Object
}
});
有趣的是,如果我使用类似https://github.com/nathanmacinnes/injectr的沙箱模块,就会出现同样的问题。这让我感到困惑的是,谁在这里做错了什么:node-sandboxed-module和injectr,node本身,should.js,还是我甚至? :)
感谢您的帮助。
答案 0 :(得分:1)
好像是节点/ V8问题。根据{{3}},Object.prototype无法提供给新的上下文:
需要注意的关键问题是V8无法直接控制上下文中使用的全局对象。因此,虽然沙箱对象的属性在上下文中可用,但沙箱原型中的任何属性都可能无法使用。
所以我必须找到一个解决方法。我可以避免使用.should属性并执行(object.prop1 === value).should.equal(true);
而不是object.prop1.should.equal(value);
之类的操作,或者只使用不扩展Object.prototype的断言lib。
答案 1 :(得分:0)
另一种解决方案是在测试模块中创建对象,因此将使用由should
修改的Object.prototype。例如:
var clone = function(obj){
return JSON.parse(JSON.stringify(obj));
}
var orig_objForTest = sandboxedModule.func(); //does not have .should property
var objForTest = clone(orig_objForTest); //has .should property
请记住,这种克隆技术会丢失对象的成员函数