笑话和酵素通过了个人测试,但未能全部通过

时间:2020-08-25 20:52:48

标签: reactjs jestjs enzyme

我进行了一些测试,以删除国家,州和城市。当我分别运行它们时,它们全部通过,但是如果我一起运行它们,则最后一次测试将失败。它具有先前测试的安装(和dom)!即expect(wrapper.text().includes('1st State')).toBe(true);失败,因为我已将其从先前的测试中删除,并且快照确认了!有人知道为什么吗?

更详细地说,如果我删除该国家/地区,则该州下的所有州和城市都将被删除,如果删除该州,则该州下的所有城市都将依此类推。

-1st Country(testid=1)
-- 1st State(testid=2)
--- 1st City(testid=3)
--- 2nd City(testid=4)
-- 2nd State(testid=5)
--- 3rd City(testid=6)

import ....

jest.mock('../apiWrappers/fetchData');

describe('<App/> Rendering using enzyme', () => {
  beforeEach(() => {
    jest.clearAllMocks();
    fetchData.mockReset();
    fetchData.mockReturnValue(Promise.resolve(data));
  });

  test('Once loaded and remove the first country', async () => {
    const wrapper = mount(<App />);
    await waitForExpect(() => {
      expect(fetchData).toHaveBeenCalledTimes(1);
      wrapper.update();
    });
    wrapper.find('[data-testid="removeDataRow-1"]').at(0).simulate('click');

    expect(wrapper.text().includes('1st Country')).toBe(false);
    expect(wrapper.text().includes('2nd Country')).toBe(true);
    expect(toJson(wrapper)).toMatchSnapshot();
  });

  test('Once loaded and remove the first state', async () => {
    const wrapper = mount(<App />);
    await waitForExpect(() => {
      expect(fetchData).toHaveBeenCalledTimes(1);
      wrapper.update();
    });

    wrapper.find('[data-testid="removeDataRow-2"]').at(0).simulate('click');

    expect(wrapper.text().includes('1st Country')).toBe(true);
    expect(wrapper.text().includes('1st State')).toBe(false);
    expect(wrapper.text().includes('1st City')).toBe(false);
    expect(wrapper.text().includes('2nd City')).toBe(false);
    expect(wrapper.text().includes('2nd State')).toBe(true);
  });

  test('Once loaded and remove the first City', async () => {
    const wrapper = mount(<App />);
    await waitForExpect(() => {
      expect(fetchData).toHaveBeenCalledTimes(1);
      wrapper.update();
    });

    expect(wrapper.text().includes('1st State')).toBe(true);
    wrapper.find('[data-testid="removeDataRow-3"]').at(0).simulate('click');

    expect(wrapper.text().includes('1st Country')).toBe(true);
    expect(wrapper.text().includes('1st State')).toBe(true);
    expect(wrapper.text().includes('1st City')).toBe(false);
    expect(wrapper.text().includes('2nd City')).toBe(true);
  });
});

App.js

// @flow
import React, { useEffect, useState } from 'react';
import FilterSection from '../components/FilterSection';
import Sidebar from '../components/Sidebar';
import fetchData from '../apiWrappers/fetchData';

const App = () => {
  const [data, setData] = useState([]);
  const [loading, setLoading] = useState(true);
  const [setting, setSetting] = useState({ hide: '3', loadedData: [] });

  useEffect(() => {
    const getData = async () => {
      try {
        const newData = await fetchData();
        setData(newData);
        setSetting({ ...setting, loadedData: newData });
        setLoading(false);
      }
      catch (e) {
        setLoading(false);
      }
    };
    getData();
    // eslint-disable-next-line
  }, []);

  const handleRemoveDataRow = (parents:Array<number>) => {
    // remove the country with id === parents[0]
    if (parents.length === 1) {
      let newData = [...data];
      newData = newData.filter(
        item => [parents[0]].indexOf(item.id) === -1,
      );
      setData(newData);
    }
    // remove the state with id === parents[1]
    else if (parents.length === 2) {
      const newData = [...data];
      const countryIndex = newData.findIndex((row) => row.id === parents[0]);
      newData[countryIndex].states = newData[countryIndex].states.filter(
        (item) => [parents[1]].indexOf(item.id) === -1,
      );
      setData(newData);
    } else if (parents.length === 3) {
    // remove the city with id === parents[2]
      const newData = [...data];
      const countryIndex = newData.findIndex((row) => row.id === parents[0]);
      const stateIndex = newData[countryIndex].states.findIndex((row) => row.id === parents[1]);
      newData[countryIndex].states[stateIndex].cities = newData[countryIndex].states[stateIndex]
        .cities.filter(
          (item) => [parents[2]].indexOf(item.id) === -1,
        );
      setData(newData);
    }
  };

  const onChangeFilterValue = (e) => setSetting({ ...setting, hide: e.target.value });
  const onChangeSearch = (e) => {
    if (!loading) {
      const newData = setting.loadedData.filter(
        (x) => x.name.toLowerCase().includes(e.target.value.toLowerCase()),
      );
      setData(newData);
    }
  };
  return (
    <>
      <FilterSection
        onChangeSearch={onChangeSearch}
        onChangeFilterValue={onChangeFilterValue}
        filterValue={setting.hide}
      />
      {!loading
        ? (
          <Sidebar
            items={data}
            onRemoveDataRow={handleRemoveDataRow}
            hide={parseInt(setting.hide, 10)}
          />
        )
        : <span>Loading List</span>}
    </>
  );
};
export default App;

1 个答案:

答案 0 :(得分:1)

我没有足够的上下文了解如何从主状态中删除这些值,但是我认为在您的App中,您正在第二次测试中变异data变量的值,并且第三个错误的值。您可以确认在每个测试中放置console.log(data)可以看到差异(每个测试应该相等)。如果这是您的问题,则不应该在您的应用中对其进行更改,一种解决方法是在您的data中创建一个新的beforeEach

工作示例将data更改为部分代码: https://stackblitz.com/edit/mutating-data?file=index.js

不进行更改,创建一个新的data https://stackblitz.com/edit/creating-a-new-data?file=index.js