我进行了一些测试,以删除国家,州和城市。当我分别运行它们时,它们全部通过,但是如果我一起运行它们,则最后一次测试将失败。它具有先前测试的安装(和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;
答案 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