1

I am trying to write the Jest-enzyme test case for useEffect react hooks, and I am really lost, I want to write test case for 2 react hooks, one making the async call and another sorting the data and setting the data using usestate hooks, my file is here.

export const DatasetTable: React.FC<DatasetTableProps> = ({id, dataset, setDataset, datasetError, setDataSetError}) => {
    const [sortedDataset, setSortedDataset] = useState<Dataset[]>();

    useEffect(() => {
        fetchRegistryFunction({
            route:`/dataset/report?${constructQueryParams({id})}`,
            setData: setDataset,
            setError: setDataSetError
        })();
    }, [id, setDataset, setDataSetError]});

    useEffect(() => {
        if(dataset) {
            const sortedDatasetVal = [...dataset];
            sortedDatasetVal.sort(a, b) => {
                const dateA: any = new Date(a.date);
                const dateA: any = new Date(a.date);
                return dataA - dateB;
            }
            setSortedDataset(sortedDatasetVal);
        }
    }, [dataset])

    return (
        <div>
            <DatasetTable
                origin="Datasets"
                tableData={sortedDataset}
                displayColumns={datasetColumns}
                errorMessage={datasetError}
            />

        </div>
    );
}
skyboyer
  • 22,209
  • 7
  • 57
  • 64
Suman
  • 33
  • 1
  • 1
  • 5

2 Answers2

1

Enzyme isn't the right library for this kind of testing.

https://react-hooks-testing-library.com/ is what you need.

In your case I would extract all the data fetching to a 'custom hook' and then test this independently from your UI presentation layer.

In doing so you have better separation of concerns and your custom hook can be used in other similar react components.

Ed Knowles
  • 1,925
  • 1
  • 16
  • 24
1

I managed to get enzyme to work with a data fetching useEffect hook. It does however require that you allow your dataFetching functions to be passed as props to the component.

Here's how I would go about testing your component, considering it now accepts fetchRegistryFunction as a prop:

const someDataSet = DataSet[] // mock your response object here.

describe('DatasetTable', () => {
  let fetchRegistryFunction;
  let wrapper;

  beforeEach(async () => {
    fetchRegistryFunction = jest.fn()
      .mockImplementation(() => Promise.resolve(someDataSet));

    await act(async () => {
      wrapper = mount(
        <DatasetTable
          fetchRegistryFunction={fetchRegistryFunction}
          // ... other props here
        />,
      );
    });

    // The wrapper.update call changes everything, 
    // act seems to not automatically update the wrapper, 
    // which lets you validate your old rendered state
    // before updating it.
    wrapper.update(); 
  });

  afterEach(() => {
    wrapper.unmount();
    jest.restoreAllMocks();
  });

  it('should display fetched data', () => {
    expect(wrapper.find(DatasetTable).props().tableData)
      .toEqual(someDataSet);
  });
});

Hope this helps!