如何在玩笑测试期间初始化反应 usecontext 状态值?
How to initialize react usecontext state value during jest tests?
我有用户可以点击成分的代码,然后我将他选择的成分存储在上下文中并将他重定向到详细信息页面:
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 Whosebug/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
我有用户可以点击成分的代码,然后我将他选择的成分存储在上下文中并将他重定向到详细信息页面:
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 Whosebug/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