簡體   English   中英

如何使用快照在 useEffect 內部使用異步回調測試功能組件

[英]How to test functional component with async callback inside useEffect using snapshots

我正在嘗試在我的組件上編寫單元測試,它看起來像這樣。

export const myComponent = ({text, list, getData = transport.getData}) => {
const [rows, setRows] = React.useState([]);

    React.useEffect(() => {
        const fetchData = async () => {
           const rows = await getData(list);
           setRows(rows);
        };
        fetchData();
    }, [list]);

    if (rows.length === 0) {
       return null;
    }

    return (
        // some JSX
    );
};

問題是組件通過 async 函數獲取數據,所以它會在組件檢查rows是否為空並返回 null 后調用。

if (rows.length === 0) {
   return null;
}

我嘲笑了getData所以它應該返回一些值。 但是,我仍然無法理解我應該如何通過單元測試來覆蓋這個組件。 我想它應該是快照,也許它不正確。

我的測試:

import React from 'react';
import {myComponent} from '../components/myComponent';
import renderer from 'react-test-renderer';

describe('myComponent', () => {
    test('should renders correctly', async () => {
        const mock = {
            text: 'text',
            list: [],
            getData: () =>
                Promise.resolve([
                    {
                        // ...
                    },
                ]),
        };
        const component = renderer.create(<myComponent text={mock.text} 
list={mock.list} getData={mock.getData}/>);
        let popup = component.toJSON();
        expect(popup).toMatchSnapshot();
    });
});

這是單元測試解決方案:

index.tsx

import React from 'react';

const transport = {
  async getData(list) {
    return [{ id: 1 }];
  }
};

export const MyComponent = ({ text, list, getData = transport.getData }) => {
  const [rows, setRows] = React.useState<any[]>([]);

  React.useEffect(() => {
    console.count('useEffect');
    const fetchData = async () => {
      console.count('fetchData');
      const newRows = await getData(list);
      setRows(newRows);
    };
    fetchData();
  }, [list]);

  if (rows.length === 0) {
    return null;
  }

  return <div>rows count: {rows.length}</div>;
};

index.spec.tsx

import React from 'react';
import { MyComponent } from './';
import renderer, { act } from 'react-test-renderer';

describe('myComponent', () => {
  test('should renders correctly', async () => {
    const mProps = {
      text: 'text',
      list: [],
      getData: jest.fn().mockResolvedValueOnce([{ id: 1 }, { id: 2 }, { id: 3 }])
    };
    let component;
    await act(async () => {
      component = renderer.create(<MyComponent {...mProps}></MyComponent>);
    });
    expect(component.toJSON()).toMatchSnapshot();
  });
});

單元測試結果:

PASS  src/stackoverflow/57778786/index.spec.tsx
  myComponent
    ✓ should renders correctly (29ms)

  console.count src/stackoverflow/57778786/index.tsx:13
    useEffect: 1

  console.count src/stackoverflow/57778786/index.tsx:15
    fetchData: 1

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   1 passed, 1 total
Time:        3.557s, estimated 8s

index.spec.tsx.snap

// Jest Snapshot v1

exports[`myComponent should renders correctly 1`] = `
<div>
  rows count: 
  3
</div>
`;

源代碼: https : //github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57778786

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM