我有以下react函数组件:
const AssetsPage = () => {
const [filteredAssets, setFilteredAssets] = useState<Asset[]>([]);
const assetsState = useAppSelector(selectAssets);
...
useEffect(() => {
setFilteredAssets(
assetsState.assets
);
}, [assetsState.assets])
useEffect(() => {
store.dispatch(fetchAssetsAsync(null));
}, [])
const columns: GridColDef[] = [
...some column definitions...
];
return (
<>
<Typography variant="h2" ml={2}>
{t("Asset.Title")}
</Typography>
<DataTable
rows={filteredAssets}
columns={columns}
rowId="globalId"
/>
</>
)
}
export default AssetsPage
和相应的切片:
import {Asset} from "../../models/Asset";
import {createAsyncThunkWithErrorHandling} from "../../utils/thunkHelper";
import {createSlice} from "@reduxjs/toolkit";
import {RootState} from "../../app/store";
import {createAsset, deleteAsset, getAssets, updateAsset} from "../../api/assets";
const initialState = {
isLoaded: false,
assets: [] as Asset[],
}
...
export const fetchAssetsAsync = createAsyncThunkWithErrorHandling(
"assets/fetch",
async (payload: string) => {
return await getAssets(payload);
}
)
...
export const oeeAssetsSlice = createSlice({
name: "assets",
initialState,
reducers: {},
extraReducers: (builder) => {
builder.addCase(fetchAssetsAsync.fulfilled, (state, action) => {
state.isLoaded = true;
state.assets = [
...action.payload,
];
});
...
}
})
export const selectAssets = (state: RootState) => state.assets;
export default oeeAssetsSlice.reducer;
这工作得很好,它从后端加载数据(或者,如果我将fetchAssetsAsync
实现替换为静态数据,它将正确加载它)。
我正在尝试做一些单元测试。渲染空表工作正常:但是无论我怎么尝试,我都无法将数据注入到assetsState
。
import {fireEvent, render, screen, waitFor} from "@testing-library/react";
import {Provider} from "react-redux";
import {RootState, store} from "../../../app/store";
import AssetsPage from "./AssetsPage";
import {createTheme} from "@mui/material/styles";
import {ThemeOptions} from "../../ThemeOptions/ThemeOptions";
import {ThemeProvider} from "@mui/material";
import oeeAssetsReducer, {selectAssets} from "../../../features/assets/oeeAssetsSlice";
import {useAppSelector} from "../../../app/hooks";
import appReducer from "../../../features/app/appSlice";
import userReducer from "../../../features/user/userSlice";
describe("AssetListPage", () => {
const theme = createTheme(ThemeOptions);
// This test works fine.
test("renders the empty component", async () => {
render(
<ThemeProvider theme={theme}>
<Provider store={store}>
<AssetsPage/>
</Provider>
</ThemeProvider>
);
expect(screen.getByText("No rows")).toBeInTheDocument();
});
// todo: this doesnt work.
const asset = {
globalId: "asset-1",
description: "test asset",
businessUnitCode: "bu-1",
localId: "123",
enabledFlag: 1,
};
jest.mock("../../../app/hooks", () => ({
useAppSelector: (selectAssets: any) => ({
assetsState: {
isLoaded: true,
assets: [asset]
}
})
}));
jest.mock("react-i18next", () => ({
useTranslation: () => ({
t: (key: string) => key
})
}));
test("renders the component with one data line", async () => {
render(<ThemeProvider theme={theme}>
<Provider store={store}>
<AssetsPage/>
</Provider>
</ThemeProvider>
);
render(
<ThemeProvider theme={theme}>
<Provider store={store}>
<AssetsPage/>
</Provider>
</ThemeProvider>
);
expect(screen.getByText("Asset.GlobalAssetId")).toBeInTheDocument();
expect(screen.getByText("Asset.Description")).toBeInTheDocument();
expect(screen.getByText("Asset.BusinessUnit")).toBeInTheDocument();
expect(screen.getByText("Asset.LocalId")).toBeInTheDocument(); // it renders the "empty table" instead
expect(screen.getByText("Asset.Disable")).toBeInTheDocument();
expect(screen.getByText("Asset.Actions")).toBeInTheDocument();
})
});
测试总是呈现一个没有任何数据的表。我在这里错过了什么?我不能安装Enzyme,试着将其喂给chatGPT,但到目前为止没有任何效果。
1条答案
按热度按时间ecfdbz9o1#
以下是一个可能的解决方案:
一些看不见的功能的解释: