여행 상품과 옵션의 개수에 따라 가격을 계산하기
test.only("update product's total when products change", async () => {
render(<Type orderType="products" />);
const productsTotal = screen.getByText("상품 총 가격:", { exact: false });
expect(productsTotal).toHaveTextContent("0");
// 아메리카 여행 상품 한개 올리기
const americaInput = await screen.findByRole("spinbutton", {
name: "America",
});
userEvent.clear(americaInput);
userEvent.type(americaInput, "1");
console.log("use", productsTotal.textContent);
expect(productsTotal).toHaveTextContent("1000");
});
findByRole
를 사용한 이유 :
이전에 데이터를 먼저 불러온 다음 진행해야 하기 때문에 비동기 요청이 알맞다.
userEvent.clear()
input 이나 textarea에 텍스트를 선택한 후 제거를 해야한다.
why ? => 현재는 없어도 영향은 없지만 위에서 같은 엘레멘트를 참조 했다면 clear를 해주는 것이 원칙
userEvent.type
input의 값을 입력해주는 함수
const americaInput = await screen.findByRole("spinbutton", {
name: "America",
});
userEvent.clear(americaInput);
userEvent.type(americaInput, "2");
const englandInput = await screen.findByRole("spinbutton", {
name: "England",
});
userEvent.clear(englandInput);
userEvent.type(englandInput, "3");
const insuranceCheckbox = await screen.findByRole("checkbox", {
name: "Insurance",
});
userEvent.click(insuranceCheckbox);
const orderButton = screen.getByRole("button", {
name: "주문하기",
});
userEvent.click(orderButton);
const summaryHeading = screen.getByRole("heading", {
name: "주문 확인",
});
expect(summaryHeading).toBeInTheDocument();
const productsHeading = screen.getByRole("heading", {
name: "여행 상품: 5000",
});
expect(productsHeading).toBeInTheDocument();
// 클릭한 내용들이 잘 적용되어 있는지 확인
expect(screen.getByText("2 America")).toBeInTheDocument();
expect(screen.getByText("3 England")).toBeInTheDocument();
expect(screen.getByText("Insurance")).toBeInTheDocument();
toBeInTheDocument()
주문 완료를 누르면 backend 로 요청을 보냈다가 응답으로 주문번호와 가격을 받아온다.
이 값들을 받아오기 전까지 loading 을 띄우다가 값을 받으면 데이터를 보여준다.
우선 데이터를 생성 완료 했다는 mock api를 만들어야한다.
rest.post("http://localhost:5001/order", (req, res, ctx) => {
let dummyData = [{ orderNumber: 2131234324, price: 2000 }];
return res(ctx.json(dummyData));
}),
const loading = screen.getByText(/loading/i);
expect(loading).toBeInTheDocument();
const completeHeader = await screen.findByRole("heading", {
name: "주문이 성공했습니다.",
});
expect(completeHeader).toBeInTheDocument();
const loadingDisappeared = screen.queryByText("loading");
expect(loadingDisappeared).not.toBeInTheDocument();
const firstPageButton = screen.getByRole("button", {
name: "첫페이지로",
});
userEvent.click(firstPageButton);
const productsTotal = screen.getByText("상품 총 가격: 0");
expect(productsTotal).toBeInTheDocument();
const optionsTotal = screen.getByText("옵션 총 가격: 0");
expect(optionsTotal).toBeInTheDocument();
await waitFor(() => {
screen.getByRole("spinbutton", { name: "America" });
});
waitFor(() => {})
마지막을 waitFor 로 적은 이유 ?
첫페이지로 가는 버튼을 누른 상태여서 새로운 페이지를 렌더링 한다 => 하지만 이미 테스트가 끝났기 때문에act 에러
가 날 것이고 , 이 요청을 기다리는 이유이다.
평소 사용하는 await screen.findByRole() 과 동일하게 사용할 수 있다.