Как правильно ждать реактивных переменных в тестах?
Учитывая реактивную переменную
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(...).
Чего я не понимаю.
Каким образом мой тест будет правильно ждать изменения реактивной переменной?