0

我目前正在尝试使用https://github.com/felixge/node-sandboxed-module以便能够在单元测试中注入依赖模拟。结果这个模块杀死了在沙盒模块中创建的对象的 should.js:

我的模块.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 ,也会出现同样的问题。这让我很困惑谁在这里做错了:节点沙盒模块和注入器,节点本身,should.js,甚至是我?:)

谢谢你的帮助。

4

2 回答 2

1

似乎这是一个节点/V8 问题。根据node.js docs, Object.prototype 不能提供给新的上下文:

需要注意的关键问题是 V8 无法直接控制在上下文中使用的全局对象。因此,虽然沙盒对象的属性将在上下文中可用,但沙盒原型中的任何属性都可能不可用。

所以我必须找到一个解决方法。我可以避免使用 .should 属性,而是使用不扩展 Object.prototype 的断言库来(object.prop1 === value).should.equal(true);代替或干脆使用断言库。object.prop1.should.equal(value);

于 2013-04-29T07:49:14.177 回答
0

另一种解决方案是在测试模块中创建对象,因此should将使用 Object.prototype modified by。例如:

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

请记住,这种克隆技术会丢失对象的成员函数

于 2013-11-20T07:31:36.513 回答