使用jasmine测试嵌套对象

时间:2014-04-03 19:54:24

标签: javascript mocking tdd jasmine

这是我的测试

describe("setTimer", function () {
      it("set status timer values from parameters and sets timer.visible to true", function(){
        var boxNumber = 1,
          time = 15;
        myObject.setTimer(boxNumber, time);
        expect(anotherObject.status.timer.boxNum).toBe(boxNumber);
        expect(anotherObject.status.timer.seconds).toBe(time);
      })
  });

这是代码

 setTimer: function (boxNum, seconds) {
    anotherObject.status.timer.boxNum = boxNum;
    anotherObject.status.timer.seconds = seconds;
    anotherObject.status.timer.visible = true;
  },

这是我得到的错误

TypeError: Cannot read property 'timer' of undefined

我尝试使用anotherObject = {}设置对象我尝试设置anotherObject.status = {}并最后尝试设置anotherObject.status.timer = {},但我仍然收到错误。任何想法,我怎么嘲笑对象?

2 个答案:

答案 0 :(得分:1)

在不知道构造anotherObject'的方式/位置的情况下,我认为在测试中执行setTimer函数之前需要初始化'anotherObject'。

你有'anotherObject'存在的init()或setup()函数会为你初始化'timer'对象吗?

虽然该方法看起来只是试图确保该方法正在设置所有相应的属性。

在测试中调用setTimer之前,您可以执行以下操作

describe("setTimer", function () {
  it("set status timer values from parameters and sets timer.visible to true", function(){
    var boxNumber = 1,
      time = 15;

    //Initialize the anotherObject
    anotherObject.status = { timer : {} }

    myObject.setTimer(boxNumber, time);
    expect(anotherObject.status.timer.boxNum).toBe(boxNumber);
    expect(anotherObject.status.timer.seconds).toBe(time);
  })
});

这当然伴随着一个警告,你现在已经使用全局范围在测试中定义了'anotherObject'(因为在javascript中排除任何变量定义的var使其成为全局范围)。这可能影响其他期望定时器对象以某种方式设置的测试用例,但是你的测试用例现在已经将定时器值分别设置为1和15(可能有很多其他值都取决于测试用例正在做什么)。

所以为了帮助解决这个问题,在测试开始或结束时重置'anotherObject'将有助于污染

afterEach(function(){ 
    anotherObject.status = { timer : {} }
})

beforeEach(function(){
    anotherObject.status = { timer : {} }
})

当然如果你在'anotherObject'上有一个init(),create()或setup()函数可以使用它当然会给你更真实的结果,因为这个对象会更接近它看起来像是在制作中。

答案 1 :(得分:0)

你没有在同一个"另一个对象"源代码和测试代码中的对象。

每个代码都有自己的对象,而另一个代码的设置值不会在另一个代码中设置。