reactjs 在jest中模拟动态html元素

tf7tbtn2  于 2023-01-12  发布在  React
关注(0)|答案(4)|浏览(147)

我想为一个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
8iwquhpp

8iwquhpp1#

我建议你使用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文件也是一个好主意,因为它是实用程序文件的依赖项,所以当它发生变化时不会影响单元测试。

2ekbmq32

2ekbmq322#

我能想到两个选项,您可以选择其中一个:
1.选中函数activeListItem的listItem

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

1.在测试用例中添加伪元素

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');
});
xtfmy6hx

xtfmy6hx3#

这条线有问题:

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

在jest中首先创建用于mock的元素。确保等待文档并注入它。
你所做的就是在元素还没有准备好测试/在这个上下文中不存在的时候获取元素。
---编辑以添加示例---
需要补充的内容:https://jestjs.io/docs/en/configuration#setupfiles-array
其他人用示例解决方案回应类似问题:https://stackoverflow.com/a/41186342/5768332

ckx4rj1h

ckx4rj1h4#

前两个答案的组合对我来说效果很好:

...

beforeAll(() => {
  const modalDiv = document.createElement("div");
  modalDiv.setAttribute("id", "react-modal-container");
  document.body.appendChild(modalDiv);
});

...

相关问题