【问题标题】:Mock dynamic html element in jest开玩笑地模拟动态 html 元素
【发布时间】:2019-11-09 03:31:14
【问题描述】:

我想为 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

【问题讨论】:

    标签: javascript reactjs mocking jestjs


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      这行有问题:

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

      首先创建元素用于开玩笑。请务必等待文档并注入它。

      您所做的是在尚未准备好测试/在此上下文中不存在时获取元素。

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

      需要补充的: https://jestjs.io/docs/en/configuration#setupfiles-array

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

      【讨论】:

      • 我是开玩笑的新手。你能给我看一个代码示例吗?
      • 是的,添加了对问题的引用和需要使用的配置
      【解决方案3】:

      我能想到两个选项,你可以选择其中一个:

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

      【讨论】:

      • let newDiv = document.createElement("div"); 中的文档将为空。当我更正时,会发生错误吗?
      • 您的第二个选项几乎可以工作,但 expect(listItem.style.backgroundColor) 为空我认为导入 variables.scss 肯定有问题。如果我将 variables.whiteGray 更改为 #ededed 它可以工作
      • 尝试this在测试文件中导入scss
      猜你喜欢
      • 2018-10-29
      • 2017-07-01
      • 1970-01-01
      • 2023-03-08
      • 2020-03-05
      • 1970-01-01
      • 1970-01-01
      • 2019-03-23
      • 2020-11-18
      相关资源
      最近更新 更多