【问题标题】:test document.body.appendChild being called in useScript React hook (Jest / Enzyme)测试 document.body.appendChild 在 useScript React hook (Jest / Enzyme) 中被调用
【发布时间】:2021-07-26 16:30:35
【问题描述】:

我正在 Jest 中为这个 useScript 钩子编写单元测试: https://usehooks.com/useScript/

我的项目使用 Jest / Enzyme 进行测试(我们不使用 React 测试库)

我正在尝试测试 document.body.appendChild 是否已被调用,但是当我运行测试时,我会从 Jest 得到以下响应:

预期:ObjectContaining {"src": “https://code.jquery.com/jquery-3.6.0.slim.min.js”,“类型”: “文本/javascript”} 调用次数:0

useHook 脚本的简化版:

export const useScript = (src) => {
      const [status, setStatus] = useState(src ? 'loading' : 'idle');
      useEffect(
        () => {
          if (!src) {
            setStatus('idle');
            return;
          }
          let script = document.querySelector(`script[src="${src}"]`);
          if (!script) {
            script = document.createElement('script');
            console.log(`document: ${document}`);
            script.src = src;
            script.async = true;
            script.setAttribute('data-status', 'loading');
            document.body.appendChild(script);
          }
        },
        [src] 
      );
      return status;
    };

玩笑测试:

import { useEffect, useState } from 'react';
import { useScript } from '../useScript';

const mockSetStatus = jest.fn();

jest.mock('../../../makeScriptDOMElement');
jest.mock('react');

const mockScriptSrc = 'https://code.jquery.com/jquery-3.6.0.slim.min.js';

describe('useScript', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });
  
   it('should append the script to the document body', async () => {
    useState.mockReturnValueOnce(['loading', mockSetStatus]);
    useScript(mockScriptSrc);
    const [effect] = useEffect.mock.calls[0];
    await effect();

    jest.spyOn(document.body, 'appendChild');
    expect(document.body.appendChild).toBeCalledWith(
      expect.objectContaining({
        type: 'text/javascript',
        src: mockScriptSrc,
      })
    );
  });
 });

【问题讨论】:

    标签: javascript reactjs jestjs react-hooks enzyme


    【解决方案1】:

    您应该在执行effect 函数之前监视document.body.appendChild() 方法。

    it('should append the script to the document body', async () => {
        jest.spyOn(document.body, 'appendChild');
        useState.mockReturnValueOnce(['loading', mockSetStatus]);
        useScript(mockScriptSrc);
        const [effect] = useEffect.mock.calls[0];
        await effect();
    
        expect(document.body.appendChild).toBeCalledWith(
          expect.objectContaining({
            type: 'text/javascript',
            src: mockScriptSrc,
          })
        );
      });
    

    【讨论】:

      猜你喜欢
      • 2020-06-09
      • 2020-09-07
      • 2021-09-16
      • 2017-02-12
      • 2020-08-07
      • 2017-11-26
      • 2019-01-29
      • 1970-01-01
      • 2020-01-18
      相关资源
      最近更新 更多