#jestjs #apollo-client #react-testing-library #reactive-variable
#jestjs #apollo-клиент #реагировать-тестирование-библиотека #реактивная переменная
Вопрос:
Учитывая реактивную переменную
export const isLoggedInVar: ReactiveVar<boolean> = cache.makeVar<boolean>(
!!localStorage.getItem("apiToken")
);
Выход из системы упрощен как:
function useLogout(): Dispatch<SetStateAction<boolean>> {
const client = useApolloClient();
const [loggedOut, setLogout] = useState(false);
useEffect(() => {
const resetCache = async (): Promise<void> => {
localStorage.clear(); // remove api token
isLoggedInVar(false); // update reactive variable
client.resetStore();
};
if (loggedOut) {
resetCache();
}
}, [loggedOut, client]);
return setLogout;
}
И компонент, который вызывает перехват:
const ProfileHeader: React.FC = () => {
const setLogout = useLogout();
return isLoggedInVar() ? (
<p>
<Link to="/settings/">
<span className="m-auto">Settings</span>
</Link>
<button
type="button"
data-testid="logout-button"
onClick={(): void => setLogout(true)}
>
Log out
</button>
</p>
) : null;
};
Когда я пишу тест для компонента, я вынужден использовать await waitFor(() => {});
в тесте.
describe("ProfileHeader", () => {
it("should allow users to logout", async () => {
isLoggedInVar(true);
const { container, getByTestId, queryByTestId } = renderApollo(
<MemoryRouter>
<ProfileHeader />
</MemoryRouter>
);
expect(isLoggedInVar()).toBeTruthy();
expect(getByTestId("logout-button")).toBeTruthy();
userEvent.click(getByTestId("logout-button"));
waitForElementToBeRemoved(queryByTestId("logout-button"));
expect(localStorage.getItem("apiToken")).toBeNull();
// await new Promise((resolve) => setTimeout(resolve, 0)); // works too
await waitFor(() => {});
expect(isLoggedInVar()).toBeFalsy();
});
});
Но в документации библиотеки тестирования упоминается:
использование пустого обратного вызова считается плохой практикой, потому что это сделает тесты более хрупкими.
Я действительно хочу сделать:
- await waitFor(() => {});
- expect(isLoggedInVar()).toBeFalsy();
await waitFor(() => expect(isLoggedInVar()).toBeFalsy());
Но это дает мне бесчисленные ошибки
Обновление ProfileHeader внутри теста не было выполнено в act(…).
Чего я не понимаю.
Каков был бы правильный способ для моего теста дождаться изменения реактивной переменной?
Комментарии:
1. Откуда вы знаете, что мы должны их ждать? Каждый раз, когда я выполняю действие, которое устанавливает мою реактивную переменную в мой тестовый файл, функция не определена