在玩笑中模拟动态 html 元素

WeS*_*eSt 5 javascript mocking reactjs 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;
}
Run Code Online (Sandbox Code Playgroud)

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');
});
Run Code Online (Sandbox Code Playgroud)

错误

TypeError: Cannot read property 'style' of null
Run Code Online (Sandbox Code Playgroud)

Ten*_*eff 11

我建议你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();
    });
  });
});
Run Code Online (Sandbox Code Playgroud)

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


小智 6

我能想到的有两种选择,你可以选择其中一种:

  1. 检查函数 activeListItem 的 listItem

    export function activeListItem(props) {
         let listItem = document.getElementById(props.id);
         if (listItem === null) {
              return;
         }
         listItem.style.backgroundColor = variables.whiteGray;
         return listItem;
     }
    
    Run Code Online (Sandbox Code Playgroud)
  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');
    });
    
    Run Code Online (Sandbox Code Playgroud)