How do I test recoil using react jest?
I expect below test is going to be success but it gives me fail.
Any way to render the status of isLogin: false
using jest?
// src/state/user.ts
import { atom } from "recoil";
export type UserType = {
isLogin: boolean;
};
const userState = atom<UserType>({
key: "user",
default: {
isLogin: true,
},
});
export default userState;
// src/pages/user/User.tsx
import { useNavigate, useParams } from "react-router-dom";
import { useRecoilValue } from "recoil";
import userState from "../../state/user";
export default function User() {
const navigate = useNavigate();
const { id } = useParams();
const { isLogin } = useRecoilValue(userState);
if (!isLogin) {
return <div>Login 후 이용 가능합니다.</div>;
}
return (
<div>
{id}
<button
type="button"
onClick={() => {
navigate("/");
}}
>
Go to Home
</button>
</div>
);
}
// src/pages/user/User.test.tsx
import { MemoryRouter } from "react-router-dom";
import { render, screen, renderHook, act } from "@testing-library/react";
import { RecoilRoot, useSetRecoilState } from "recoil";
import User from "./User";
import type { UserType } from "../../state/user";
import userState from "../../state/user";
const userStateMock = (user: UserType) => {
const { result } = renderHook(() => useSetRecoilState(userState), {
wrapper: RecoilRoot,
});
act(() => {
result.current(user);
});
return result;
};
describe("<User />", () => {
const renderUserComponent = () =>
render(
<RecoilRoot>
<MemoryRouter>
<User />
</MemoryRouter>
</RecoilRoot>
);
describe("When user hasn't logged in", () => {
it("Should render warning message", () => {
userStateMock({
isLogin: false,
});
renderUserComponent();
expect(screen.getByText(/Login 후 이용 가능합니다./)).toBeDefined();
});
});
});
Result of the test
You should use the initializeState
prop in the RecoilRoot component to pass a function that initializes the state of the atoms present in the MutableSnapshot instance. This way you can mock Recoil state data in your tests.
const mockedState = { isLogin: false }
const renderUserComponent = () =>
render(
<RecoilRoot initializeState={(snapshot) => snapshot.set(userState, mockedState)}>
<MemoryRouter>
<User />
</MemoryRouter>
</RecoilRoot>
);
Edit: Misspelled mockedState
, the original example would throw an error. Fixed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With