嘲笑动态HTML元素

时间:2019-06-27 06:51:04

标签: javascript reactjs mocking jestjs

我想为utils方法编写测试。在那种方法中,我通过id获取一个html元素,然后更改该元素的颜色。问题在于该元素仅在单击按钮后可用。如何模拟元素?

UtilListItem.js

import variables from '../stylesheets/Variables.scss';

export function activeListItem(props){
 let listItem = document.getElementById(props.id);
 listItem.style.backgroundColor = variables.whiteGray;
 return listItem;
}

UtilListeItem.test.js

it('check if the correct color is set for the acitve list item', () => {
  let props = {id:'123'}
  const listItem = activeListItem(props);
  expect(listItem.style.backgroundColor).toBe('#ededed');
});

错误

TypeError: Cannot read property 'style' of null

3 个答案:

答案 0 :(得分:0)

此行有问题:

 let listItem = document.getElementById(props.id);

首先创建一个元素以进行嘲笑。请务必等待文档并注入。

在这种情况下,您正在做的事情是获取尚待测试/不存在的元素。

---编辑以添加示例---

需要添加的内容: https://jestjs.io/docs/en/configuration#setupfiles-array

其他人通过示例解决方案对类似问题做出了回应: https://stackoverflow.com/a/41186342/5768332

答案 1 :(得分:0)

我可以想到两种选择,您可以选择其中一种:

  1. 对功能activeListItem的listItem进行检查

    export function activeListItem(props) {
         let listItem = document.getElementById(props.id);
         if (listItem === null) {
              return;
         }
         listItem.style.backgroundColor = variables.whiteGray;
         return listItem;
     }
    
  2. 在测试用例中添加虚拟元素

    it('check if the correct color is set for the acitve list item', () => {
       /** Create and add dummy div **/
        let testId = "dummy-testId";
        let newDiv = document.createElement("div");
        newDiv.setAttribute("id", testId);
        document.body.appendChild(newDiv);
    
        let props = {id: testId}
        const listItem = activeListItem(props);
        expect(listItem.style.backgroundColor).toBe('#ededed');
    });
    

答案 2 :(得分:0)

我会建议您jest.spyOn。这是监视功能和/或附加某些模拟行为的一种非常方便的方法。

您可以像这样使用它:

imoprt { activeListItem } from './utils';

let spy;
beforeAll(() => {
  spy = jest.spyOn(document, 'getElementById');
});

describe('activeListItem', () => {
  describe('with found element', () => {
    let mockElement;
    beforeAll(() => {
      // here you create the element that the document.createElement will return
      // it might be even without an id
      mockElement = document.createElement(....);
      spy.mockReturnValue(mockElement);
    });

    // and then you could expect it to have the background
    it('should have the background applied', () => {
      expect(mockElement.style.backgroundColor).toBe('#ededed');
    });
  });

  describe('without found element', () => {
    // and here you can create a scenario
    // when document.createElement returns null
    beforeAll(() => {
      spy.mockReturnValue(null);
    });

    // and expect you function not to throw an error
    it('should not throw an error', () => {
      expect(() => activeListItem({id:'123'})).not.toThrow();
    });
  });
});

模拟.scss文件也是一个好主意,因为它是实用程序文件的依赖项,因此更改时不会影响单元测试。