findBy
React Testing Library에서 DOM요소를 찾을 때 많이 쓰이는 메서드 중 하나인 findBy
는 비동기적으로 요소를 찾을 때 유용하다.
API 호출이나, 타이머처럼 일정 시간이 지난 후에 렌더링 되는 요소를 테스트할 때 주로 사용된다.
findBy
는 Promise를 반환한다. 지정된 시간 내에 해당 요소를 찾으면 resolve, 그렇지 않으면 reject 된다.
사용시기
- 데이터 패칭 이후 나타나는 요소
- setTimeout, setInterval 등으로 일정 시간이 지난 후 나타나는 요소
- 상태 변경으로 인한 렌더링 결과물
findBy
와 getBy
는 유사하지만 비동기 요소를 기다린다는 점에서 다르다.
promise를 반환하기 때문에 주로 async/await와 함께 사용된다.
const element = await findByText("로딩 완료")
작성 예시
import React, { useEffect, useState } from "react"
const UserProfile = () => {
const [loading, setLoading] = useState(true)
const [user, setUser] = useState("")
useEffect(() => {
setTimeout(() => {
setUser("홍길동")
setLoading(false)
}, 2000)
}, [])
if (loading) {
return <div>로딩 중...</div>
}
return <div>사용자 이름: {user}</div>
}
export default UserProfile
import { render, screen } from '@testing-library/react';
import UserProfile from './UserProfile';
test('사용자 이름을 API 호출 후 렌더링한다', async () => {
render(<UserProfile />);
expect(screen.getByText('로딩 중...')).toBeInTheDocument();
const userNameElement = await screen.findByText('사용자 이름: 홍길동');
expect(userNameElement).toBeInTheDocument();
});
위의 코드는 실패한다.
이유는 기본적으로 findBy가 기다리는 시간은 1000ms로 설정되어 있기 때문이다.
하지만 작성한 컴포넌트는 2000ms 뒤에 상태를 바꾸는 동작을 하기 때문에 실패하는 코드가 된다.
이를 해결하기 위해서 findBy~ ()의 3번째 인자값을 이용해서 시간을 지정할 수 있다.
const userNameElement = await screen.findByText("사용자 이름: 홍길동",{},{
timeout:2000
})
다시 작성된 테스트코드를 보면 timeout을 이용해서 기다리는 시간을 늘려 2초를 기다리는 테스트 코드로 만들었다. 그 결과 해당 테스트 코드는 통과할 수 있게 되었다.
'시작 > TIL(Today I Learned)' 카테고리의 다른 글
React Testing Tutorial (8) - getAllBy..., textMatch (0) | 2024.09.11 |
---|---|
React Testing Tutorial(7) - getByDisplayValue, getByAltText, getByTitle, getByTestId (1) | 2024.09.08 |
React Testing Tutorial(6) - getByLabelText(), getByPlaceholderText(), getByText() (0) | 2024.09.01 |
React Testing Tutorial(5) - getByRole, getByRole option (0) | 2024.08.25 |
React Testing Tutorial(4) - RTL Queries (0) | 2024.08.15 |
댓글