[Jest] Async assertion
글 작성자: 망고좋아
반응형
🎯 Async assertion
- callback 패턴의 경우 test() 함수가 제공하는 done() 함수를 활용하여 콜백이 끝나고 done()을 호출이 된다. 에러가 발생하면 done()의 인자로 에러를 넘긴다.
- Promise 패턴의 경우 async/await을 활용하거나 Promise를 리턴한다.
function isPythagoreanAsync(a, b, c) {
return new Promise(resolve => {
setTimeout(() => {
const result = isPythagorean(a, b, c)
if (result) return resolve(result)
reject(new Error("Not pythagorean"))
}, 500)
})
}
test('Should 3, 4, 5 be pythagorean async', (done) => {
isPythagoreanAsync(3, 4, 5).then(done).catch(done)
})
test('Should 3, 4, 5 be pythagorean async', () => {
return expect(isPythagoreanAsync(3, 4, 5)).resolves.toBe(true)
})
test('Should 3, 4, 6 be not pythagorean async', () => {
return expect(isPythagoreanAsync(3, 4, 6)).rejects.toBe("Not pythagorean")
})
📝 Mock functions
- jest.fn()을 활용하여 mock function 객체를 만들 수 있다.
- mockReturnValueOnce() 등으로 리턴하는 값을 임의로 조작할 수 있다. 여러 번 호출하면 순서대로 세팅된 값을 반환한다.
- mockResolvedValue()로 promise가 resolve 하는 값을 조작할 수 있다.
- jest.mock()으로 특정 모듈을 mocking 한다.
- 실제로 비동기 작업 테스트는 서버에 http 요청을 보내지 않는다.
- 서버 과부하
- post 요청 경우 실제로 db에 들어가서 변경될 수 있어서
- 따라서 fetch가 성공적으로 요청하는지는 테스트하면 안 된다.
- 요청에 대한 데이터를 받았을 때 컴포넌트가 올바르게 동작하는지 테스트해 줘야 한다.
- 그래서 fetch를 mock 함수로 대체해야 한다.
import { render, screen } from "@testing-library/react";
import Async from "./Async";
describe("비동기 컴포넌트", () => {
test("renders posts if request succeeds", async () => {
window.fetch = jest.fn(); // 내장 fetch 함수를 mock 함수로 덮어쓰기
window.fetch.mockResolvedValueOnce({
json: async () => [{ id: "p1", title: "첫 포스트!" }], // fetch를 하면 json이 반환되고 then을 해서 date를 받기 때문에 동일한 시나리오로 작성
}); // fetch가 호출될 때 resolved 되면 지정한 값을 반환
render(<Async />);
const listItemElements = await screen.findAllByRole("listitem");
// 한 개 이상의 item을 가져오니까 findAllByRole 사용
// find는 원하는 원소가 없더라도 비동기적으로 기다리게 된다.
expect(listItemElements).not.toHaveLength(0); //성공하면 빈 배열을 가져오지 않으니까 not.toHaveLength(0)를 통해서 빈 배열이 아닌지 test
});
});
- jest.fn();는 mock 함수를 만든다.
- mockResolvedValueOnce는 (한 번만) 비동기 모의 함수가 이행(Resolved) 되면 지정한 값을 반환한다.
📕 Mock functions - assertion
toHaveBeenCalled
: 이 함수가 호출되었는지 검증toHaveBeenCalledWith(arg1, arg2, ...)
: 이 함수가 특정 인자와 함께 호출되었는지 검증toHaveBeenLastCalledWith(arg1, arg2, ...)
: 마지막으로 특정 인자와 함께 호출되었는지 검증
📝 Lifecycle functions
- beforeEach
- afterEach
- beforeAll
- afterAll
beforeEach(() => {
setupMockData()
})
afterEach(() => {
clearMockData()
})
📝 Grouping
- describe()
- test()
describe('This is group 1', () => {
describe('This is inner group 1', () => {
test('Test 1', () => {})
})
describe('This is inner group 2', () => {
test('Test 2', () => {})
})
})
📝 Snapshot testing
toMatchSnapshot()
을 호출하면, 기존에 스냅샷이 없었을 경우.snap
파일을 만든다.- 기존 스냅샷이 있을 경우, 새로운 스냅샷과 비교하여 변경 사항이 있으면 테스트는 실패한다.
toMatchInlineSnapshot()
을 호출하면 별도의 스냅샷 파일을 만들지 않는다. 이 경우, 어떻게 스냅샷이 쓰였는지를 하나의 파일 안에서 알 수 있게 된다.- 코드의 길이가 길어질 수 있다. 선호도에 따라서 별도의 파일을 만들거나 하나의 파일에 만들지 결정할 수 있다.
import { render } from "@testing-library/react";
test('Snapshot test form', () => {
const { container } = render(<MyForm />)
expect(container.firstChild).toMatchSnapshot() // 별도의 파일을 만든다.
})
test('Snapshot test form', () => {
const { container } = render(<MyForm />)
expect(container.firstChild).toMatchInlineSnapshot()
})
📝 Snapshot testing
expect(container.firstChild).toMatchInlineS
napshot(`
<div>
<div>
<img
alt="Placeholder"
src="<https://via.placeholder.com/150>"
/>
</div>
<form
id="programming-form"
>
<fieldset>
<legend>
Basic Info
</legend>
<label
for="username"
>
Username
</label>
...
반응형
'프로그래밍 > testing' 카테고리의 다른 글
[react-testing-library] 유저 이벤트 (0) | 2022.01.17 |
---|---|
[react-testing-library] 쿼리의 우선순위 (0) | 2022.01.17 |
[react-testing-library] react-testing-library란? (0) | 2022.01.17 |
[Jest] Assertion Matchers 활용 (0) | 2022.01.17 |
[jest] jest란? (0) | 2022.01.17 |
댓글
이 글 공유하기
다른 글
-
[react-testing-library] 쿼리의 우선순위
[react-testing-library] 쿼리의 우선순위
2022.01.17 -
[react-testing-library] react-testing-library란?
[react-testing-library] react-testing-library란?
2022.01.17 -
[Jest] Assertion Matchers 활용
[Jest] Assertion Matchers 활용
2022.01.17 -
[jest] jest란?
[jest] jest란?
2022.01.17