文档元素的模拟对象

时间:2014-05-06 12:54:12

标签: javascript unit-testing jasmine

我有下一个测试代码:

it("Test", function() {
    loadResources();

    expect(document.getElementById('MyElement').innerHTML).toBe("my string");
});

功能体 loadResources()

document.getElementById('MyElement').innerHTML = "my string";

我的测试失败,并显示以下消息:

  

TypeError:无法将属性“innerHTML”设置为null。

看起来我需要为innerHTML创建模拟对象。我怎么能这样做?

3 个答案:

答案 0 :(得分:61)

我认为你应该模仿getElementById来返回虚拟HTMLElement

var dummyElement = document.createElement('div');
document.getElementById = jasmine.createSpy('HTML Element').andReturn(dummyElement);

现在,对于document.getElementById的每次调用,它都会返回虚拟元素。它将设置虚拟元素的innerHTML,并将其与最终的预期结果进行比较。

编辑:我想你应该用toBe替换toEqualtoBe可能会失败,因为它将测试对象标识而不是值相等。

EDIT2(关于多个身份证):我不确定,但你可以打电话给假。它将为每个ID创建一个新的HTML元素(如果它还不存在)并将其存储在对象文字中以备将来使用(即对具有相同ID的getElementById的其他调用)

var HTMLElements = {};
document.getElementById = jasmine.createSpy('HTML Element').andCallFake(function(ID) {
   if(!HTMLElements[ID]) {
      var newElement = document.createElement('div');
      HTMLElements[ID] = newElement;
   }
   return HTMLElements[ID];
});

答案 1 :(得分:2)

通过id设置文档正文和getElement。我正在开玩笑,这很好。 看看这个example from jest documentation

test('Toggle innerHtml of an element', () =>{
document.body.innerHTML =
            '<div>' +
            '  <div id="username" >Hello</div>' +
            '  <button id="button" />' +
            '</div>';
var el = document.getElementById('username');
var newText = 'new inner text';
el.innerText = newText;
expect(el.innerText).toEqual(newText);
});

答案 2 :(得分:1)

尝试一下:

it('should blah', () => {
  const elementMock = {
    innerHTML: 'my string'
  };    

  loadResources();

  jasmine.spyOn(document, 'getElementById').and.returnValue(elementMock);

  expect(document.getElementById('MyElement').innerHTML).toBe('my string');
});