在jest测试期间如何初始化react usecontext状态值?



我有代码,用户可以点击成分,然后我存储他所选择的成分在上下文中,并重定向到详细信息页面:

const [, setSelectedItem] = useContext(itemContext);
const [, setSelectedMealNumber] = useContext(selectedMealNumberContext);
const editIngredient = (event: React.MouseEvent<HTMLElement>) => {
setSelectedItem(ingredient);
setSelectedMealNumber(mealNumber);
router.push(`/i/${ingredient?.uid}`);
};

然而设置selectedItem在我的上下文提供程序中初始化为null:

// Provider component
function ApiStore({ children }) {
const [selectedItem, setSelectedItem] = useState(null);

所以当测试细节页:

it("renders the selected item productName", () => {
const queryClient = new QueryClient();
render(
<ApiStore>
<QueryClientProvider client={queryClient}>
<IngredientExpanded />
</QueryClientProvider>
</ApiStore>
);
const productName = screen.getByText(FakeItem1.productName);
expect(productName).toBeInTheDocument();
});

测试失败,因为selectedItem为null.

现在我在我的上下文提供程序中像这样手动初始化这个值,我的测试成功了:

const [selectedItem, setSelectedItem] = useState(FakeItem1);

但是因为我只需要这个值用于我的测试而不是实际的应用程序,所以我必须删除它并将其设置回null在我的生产应用程序。

我不需要嘲笑一切,因为,其他一切都工作。如何简单地注入selectedItem在我考试的时候?

最简单的方法是为ApiStore组件添加value道具。然后,您可以为上下文提供程序提供初始值。

index.ts:

import React, { useContext, useState } from 'react';
const ItemContext = React.createContext({
selectedItem: null,
setSelectedItem: (state) => {},
});
export const ApiStore = ({ children, value }) => {
const [selectedItem, setSelectedItem] = useState(value);
return <ItemContext.Provider value={{ selectedItem, setSelectedItem }}>{children}</ItemContext.Provider>;
};
export const IngredientExpanded = () => {
const { selectedItem } = useContext(ItemContext);
return <div>{selectedItem}</div>;
};

index.test.ts:

import { render, screen } from '@testing-library/react';
import '@testing-library/jest-dom/extend-expect';
import React from 'react';
import { ApiStore, IngredientExpanded } from '.';
describe('72047880', () => {
test('should find the selected item', () => {
render(
<ApiStore value={'product name'}>
<IngredientExpanded />
</ApiStore>
);
const productName = screen.getByText('product name');
expect(productName).toBeInTheDocument();
});
test('should not find the selected item', () => {
render(
<ApiStore value={null}>
<IngredientExpanded />
</ApiStore>
);
const productName = screen.queryByText('product name');
expect(productName).not.toBeInTheDocument();
});
});

测试结果:

PASS  stackoverflow/72047880/index.test.tsx (11.239 s)
72047880
✓ should find the selected item (23 ms)
✓ should not find the selected item (3 ms)
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        12.855 s

最新更新