MST

星途 面试题库

面试题:React组件测试中,如何隔离测试有副作用的函数并模拟外部依赖

在一个React组件中,调用了一个外部API函数fetchData来获取数据,并将获取的数据存储在组件状态中。请使用React测试工具,例如Jest和Sinon,编写单元测试,确保fetchData函数被正确调用,并且在模拟API返回不同数据时,组件状态能正确更新。同时,要保证测试过程中不产生真实的网络请求。
16.4万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试
  1. 安装依赖
    • 确保项目中安装了jestreact - testing - librarysinon。如果没有安装,可以使用以下命令:
    npm install --save - dev jest @testing - library/react sinon
    
  2. 假设React组件代码如下
    import React, { useState, useEffect } from'react';
    
    // 假设这是外部API函数
    const fetchData = async () => {
      // 真实实现会有网络请求,这里省略
      return { data: 'default data' };
    };
    
    const MyComponent = () => {
      const [data, setData] = useState(null);
      useEffect(() => {
        const fetch = async () => {
          const result = await fetchData();
          setData(result);
        };
        fetch();
      }, []);
    
      return <div>{data? JSON.stringify(data) : 'Loading...'}</div>;
    };
    
    export default MyComponent;
    
  3. 编写测试代码
    import React from'react';
    import { render, screen, waitFor } from '@testing - library/react';
    import sinon from'sinon';
    import MyComponent from './MyComponent';
    
    // 假设fetchData函数在MyComponent所在模块中导出
    import { fetchData } from './MyComponent';
    
    describe('MyComponent', () => {
      it('should call fetchData and update state correctly', async () => {
        const mockData = { data:'mocked data' };
        const spy = sinon.spy(fetchData, 'default').resolves(mockData);
    
        render(<MyComponent />);
    
        await waitFor(() => expect(spy.calledOnce).toBe(true));
        await waitFor(() => expect(screen.getByText('{"data":"mocked data"}')).toBeInTheDocument());
    
        spy.restore();
      });
    });
    
    • 在上述测试代码中:
      • 首先使用sinon.spyfetchData函数进行间谍操作,并让它返回模拟数据mockData
      • 然后使用@testing - library/reactrender方法渲染组件。
      • waitFor用于等待异步操作完成,第一个waitFor检查fetchData函数是否被调用一次。
      • 第二个waitFor检查组件状态更新后,正确的数据是否在DOM中显示。
      • 最后使用spy.restore()恢复fetchData函数的原始实现。这样就确保了在测试过程中不会产生真实的网络请求,并且验证了fetchData函数被正确调用以及组件状态能正确更新。