Всем доброго времени суток, возникла проблема,
Написал тест для детальной страницы
import { describe, it, expect } from "vitest";
import RenderWithRouter from "../tests/helpers/renderWithRouter.tsx";
import { screen } from "@/utils/test-utils.tsx";
import { act } from "react-dom/test-utils";
describe("CLIPS PAGE", () => {
it("Рендер спика роликов", async () => {
RenderWithRouter({
initialEntries: ["/clips"],
});
const clipsAudioItems = await screen.findAllByTestId("clips/audioItem");
const ListItemsTemplate = await screen.findByTestId("ListItemsTemplate");
expect(ListItemsTemplate).toBeInTheDocument();
expect(clipsAudioItems.length).toBe(5);
});
it("Рендер детальной страницы", async () => {
RenderWithRouter({
initialEntries: ["/clips/1482722015105"],
});
// Добавьте этот блок с использованием act
await act(async () => {
const titleDetailPage = await screen.findByTestId("detailPageTitle");
console.log(titleDetailPage);
});
});
});
Вот сам компонент, который отрировывается
import ContentDetailPage from "@/modules/DetailClip/components/ContentDetailPage/ContentDetailPage.tsx";
import { observer } from "mobx-react-lite";
import Loader from "@/components/Loader/Loader.tsx";
import classes from "./DetailClipWrapper.module.scss";
import { useAppStore } from "@/stores/useAppStore.ts";
const DetailClipWrapper = observer(() => {
const store = useAppStore();
return (
<section className={classes.section}>
{store.detailClipStore.loading ? (
<Loader className={classes.preloader} />
) : (
<ContentDetailPage />
)}
</section>
);
});
export default DetailClipWrapper;
Вот хелпер
import { MemoryRouter } from "react-router-dom";
import AppRouter from "../../router/AppRouter.tsx";
import { render, RenderResult } from "@utils/test-utils.tsx";
import React from "react";
import { AppStoreProvider } from "../../stores/AppStoreProvider.tsx";
interface IProps {
component?: React.FC;
initialEntries?: string[];
}
const renderWithRouter = ({
component: Component,
initialEntries = ["/"],
}: IProps): RenderResult => {
return render(
<MemoryRouter initialEntries={initialEntries}>
<AppStoreProvider>
<AppRouter />
{Component && <Component />}
</AppStoreProvider>
</MemoryRouter>
);
};
export default renderWithRouter;
А вот reducer mobx с которым работает компонент
import { makeAutoObservable } from "mobx";
import {
IDetailClipData,
DetailClipInterfaces,
} from "@/modules/DetailClip/types/DetailClipInterfaces.ts";
import { DetailClipMock } from "@/modules/DetailClip/mocks/DetailClipMock.ts";
class DetailClipStore implements DetailClipInterfaces {
data: IDetailClipData | null = null;
loading = false;
error: Error | null = null;
constructor() {
makeAutoObservable(this);
}
// Получение детальной информации об аудио с сервера
async fetchAudioData(/*id: number*/) {
try {
this.setLoading(true);
this.error = null;
// Имитация запроса к серверу
await new Promise((resolve) => setTimeout(resolve, 2000));
this.setData(DetailClipMock);
// обработка данных из за ассинхронности
} catch (error: unknown) {
if (error instanceof Error) {
this.error = error;
}
} finally {
this.setLoading(false);
}
}
setData(data: IDetailClipData) {
this.data = data;
}
setLoading(loading: boolean) {
this.loading = loading;
}
}
export default new DetailClipStore();
Проблема в том, что онрендерит Loading, но не ждет когда fetchAudioData закончит свой функционал.
Но когда убираешь строчку когда
await new Promise((resolve) => setTimeout(resolve, 2000));
Все работает, как победить эту проблему?
пробовал решение с act - не получилось