如何使用 Jest 和 Enzyme 测试 useEffect 中的函数?

Anshu Verma

我正在使用玩笑和酶来测试我的组件。我想在加载整个页面时加载我的组件,所以我在里面使用加载事件useEffect,这是我的代码

const RatingsAndReviews = (props: RatingsAndReviewsProps) => {

const [pageLoaded, setPageLoaded] = useState<boolean>(false)

const handleLoad = () => {
    if (document.readyState === 'complete') {
      setTimeout(() => {
        setPageLoaded(true)
      }, 1500)
    }
}

React.useEffect(() => {
    window.addEventListener('load', handleLoad)
    return () => {
      window.removeEventListener('load', handleLoad)
    }
}, [])

return (...some code)
}

我想测试这个handleLoad函数,但我无法弄清楚如何在我的组件中传递这个模拟函数,因为组件已经期望道具并且因为它是 TypeScript,所以我不能传递除所需道具之外的任何其他东西,在这里是我的测试用例

it('Should run handleLoad function onMount', ()=>{
    jest.spyOn(React, 'useEffect').mockImplementation(f => f())
    const handleLoad = jest.fn();
    wrapper = mount(<RatingsAndReviews {...propObj} />)
    expect(handleLoad).toHaveBeenCalled();
})

我收到此错误expect(jest.fn()).toHaveBeenCalled()

Expected number of calls: >= 1
Received number of calls:    0
幻灯片p2

尽量不要mock第三方库函数的实现,因为不正确的mock实现会破坏它的功能。例如,useEffect(effect)react hook 不只是执行effect函数。考虑,

React 延迟运行useEffect,直到浏览器绘制完成。

你怎么嘲笑它?不正确的模拟会导致意外的行为。您的测试可能会基于不正确的模拟实现而通过,但代码在实际运行时会失败。这就是为什么你最好不要模拟第三方库。当然,这不是绝对的。如果第三方库的功能简单且自包含,则可以模拟它们。

对于 React 组件,我们应该做黑盒测试,只测试组件的行为和功能,而不是实现。我们应该将组件视为一个单元,而不是其中的函数。

我们应该测试pageLoaded状态变化时渲染的内容。

函数组件内部定义的事件处理程序是私有的,您不能从外部访问它们(测试代码)。所以你不能直接调用它们。相反,您应该通过用户事件触发它们。您的案例的load事件。

例如

index.tsx

import React from 'react';
import { useEffect, useState } from 'react';

export const RatingsAndReviews = (props) => {
  const [pageLoaded, setPageLoaded] = useState<boolean>(false);

  console.log('pageLoaded: ', pageLoaded);
  const handleLoad = () => {
    if (document.readyState === 'complete') {
      setTimeout(() => {
        setPageLoaded(true);
      }, 1500);
    }
  };

  useEffect(() => {
    window.addEventListener('load', handleLoad);
    return () => {
      window.removeEventListener('load', handleLoad);
    };
  }, []);

  return <div>{pageLoaded ? 'loaded' : 'not loaded'}</div>;
};

index.test.tsx

import { mount } from 'enzyme';
import React from 'react';
import { act } from 'react-dom/test-utils';
import { RatingsAndReviews } from '.';

describe('RatingsAndReviews', () => {
  it('Should run handleLoad function onMount', () => {
    jest.useFakeTimers();
    const wrapper = mount(<RatingsAndReviews />);
    window.dispatchEvent(new Event('load'));
    expect(wrapper.text()).toBe('not loaded');
    act(() => {
      jest.advanceTimersByTime(1500);
    });
    expect(wrapper.text()).toBe('loaded');
  });
});

测试结果:

 PASS  stackoverflow/71953030/index.test.tsx (11.883 s)
  RatingsAndReviews
    ✓ Should run handleLoad function onMount (47 ms)

  console.log
    pageLoaded:  false

      at RatingsAndReviews (stackoverflow/71953030/index.tsx:7:11)

  console.log
    pageLoaded:  true

      at RatingsAndReviews (stackoverflow/71953030/index.tsx:7:11)

-----------|---------|----------|---------|---------|-------------------
File       | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
-----------|---------|----------|---------|---------|-------------------
All files  |   93.33 |       75 |      80 |   92.86 |                   
 index.tsx |   93.33 |       75 |      80 |   92.86 | 19                
-----------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        13.575 s, estimated 14 s

包版本:

"enzyme": "^3.11.0",
"enzyme-adapter-react-16": "^1.15.5",
"react": "^16.14.0",
"react-dom": "^16.14.0",
"jest": "^26.6.3",

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何使用Jest和Enzyme测试React中的功能

如何使用Jest&Enzyme在React中编写useEffect Hook的测试用例?

使用 Enzyme 和 Jest 在 React 中测试处理更改功能

如何在无状态组件中执行函数以在 Jest 和 Enzyme 中进行测试

使用 Jest / Enzyme 测试异步函数

如何在 React TDD 中使用 jest 和 Enzyme 测试组件的状态是否被函数更改

如何使用Jest和Enzyme测试按钮的onClick道具

如何使用Jest和Enzyme测试组件的条件渲染

如何使用Jest和Enzyme测试UI材质TextField的onChange

如何使用Enzyme和Jest在单元测试中检查嵌套的React组件的值

Jest和Enzyme使用ES6 Arrow函数测试React组件

开始使用Enzyme和Jest测试React组件

如何在React with TypeScript,Jest和Enzyme中测试按钮单击

如何通过Jest和Enzyme在React(Native)中为父组件提供功能来测试组件?

使用Jest和Enzyme测试React组件中的反跳功能

使用Jest / Enzyme测试componentDidMount中的多个提取

如何在Jest和Enzyme中触发和测试真实的粘贴事件(未通过调用道具进行模拟)

如何为Axios和Hooks实施Jest测试-useEffect

模拟点击时使用React的Jest和Enzyme进行测试会调用一个调用promise的函数

使用useEffect和jest.useFakeTimer()进行测试

使用Jest和Enzyme,如何测试通过props传递的功能?

如何使用 Jest 和 Enzyme 为简单的 React 组件编写测试用例

如何在 React 中使用 Enzyme 和 Jest 编写功能测试

如何在React with Jest和Enzyme中测试表单提交?无法读取未定义的属性“ preventDefault”

在Jest + Enzyme中测试连接的容器方法

使用 jest Enzyme 测试输入组件

使用 Jest/Enzyme 进行 FlatList 测试

在使用React Navigation和TypeScript时,如何使用Jest和Enzyme对静态navigationOptions进行单元测试?

如何使用Jest / Enzyme在React中测试文件类型输入的更改处理程序?