https://github.com/ssi02014/jest_tutorial
โจ Jest Tutorial
https://github.com/ssi02014/jest_tutorial
javascript jest
Last synced: 8 months ago
JSON representation
โจ Jest Tutorial
- Host: GitHub
- URL: https://github.com/ssi02014/jest_tutorial
- Owner: ssi02014
- Created: 2021-11-07T15:14:46.000Z (almost 4 years ago)
- Default Branch: master
- Last Pushed: 2021-11-16T15:02:32.000Z (almost 4 years ago)
- Last Synced: 2024-12-30T06:45:17.830Z (10 months ago)
- Topics: javascript, jest
- Language: JavaScript
- Homepage:
- Size: 271 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# ๐ป Jest Tutorial
## ๐ ์์
### ํจํค์ง ์ค์น
```
yarn add jest
npm install jest --save-dev
```
## โจ ํ ์คํธ ํ์ผ
```
1. (ํ์ผ์ด๋ฆ).test.js
2. __tests__
```
- `npm test(or yarn test)` ๋ช ๋ น์ด๋ฅผ ์คํํ๋ฉด ํ๋ก์ ํธ ๋ด์ ๋ชจ๋ ํ ์คํธ ํ์ผ๋ค์ ์ฐพ์์ ํ ์คํธ๋ฅผ ์งํํ๋ค.
- ์ง์ ์ ํํ ํ ์คํธ ํ์ผ๋ง ์คํ์ํค๊ณ ์ถ์ผ๋ฉด `npm test (๊ฒฝ๋ก ๋ฐ ํ์ผ ์ด๋ฆ)`์ผ๋ก ์คํํ๋ฉด ๋๋ค.
## ๐ ์ ์ฉํ Matchers ์์
- Matchers ์ฐธ๊ณ ์ฌ์ดํธ: https://jestjs.io/docs/en/expect
### ๐โโ๏ธ 1. toBe
```js
// fn.js
const fn = {
add: (num1, num2) => num1 + num2,
};module.exports = fn;
```
```js
// fn.test.js
const fn = require("./fn");test("1์ 1์ด์ผ", () => {
expect(1).toBe(1);
});test("3๋ํ๊ธฐ 3์ 5๊ฐ ์๋์ผ", () => {
expect(fn.add(3, 3)).not.toBe(5);
});
```
- `expect`์ ๊ฒ์ฆํ ๊ฐ์ ๋ฃ๊ณ , `toBe`์ ๊ธฐ๋๋๋ ๊ฐ์ ๋ฃ๋๋ค.
- `not`์ ๋ถ์ ์ ์๋ฏธํ๋ค.
### ๐โโ๏ธ 2. toEqual
```js
// fn.js
const fn = {
add: (num1, num2) => num1 + num2,
makeUser: (name, age) => {
return {
name,
age,
};
},
};
module.exports = fn;
```
```js
// fn.test.js
test("2๋ํ๊ธฐ 3์ 5์ผ", () => {
expect(fn.add(2, 3)).toEqual(5);
});test("2๋ํ๊ธฐ 3์ 5์ผ", () => {
expect(fn.add(2, 3)).toBe(5);
});test("์ด๋ฆ๊ณผ ๋์ด๋ฅผ ์ ๋ฌ๋ฐ์์ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ค", () => {
expect(fn.makeUser("minjae", 27)).toEqual({ name: "minjae", age: 27 });
});
```
- ์ผ๋ฐ์ ์ธ ๊ฐ์ `toBe`์ `toEqual`์ ๋์ผํ ๊ธฐ๋ฅ์ ํ๋ค.
- ํ์ง๋ง ๋ฐฐ์ด์ด๋ ๊ฐ์ฒด๋ ์ฌ๊ท์ ์ผ๋ก ๋๋ฉด์ ๊ฐ์ ํ์ธํ๊ธฐ ๋๋ฌธ์ `toBe`๊ฐ ์๋ `toEqual`์ ์ฌ์ฉํด์ผ ํ๋ค. (`toBe`๋ ์ค๋ฅ ๋ฐ์)
### ๐โโ๏ธ 3. toStrictEqual
```js
// fn.js
const fn = {
add: (num1, num2) => num1 + num2,
makeUser: (name, age) => {
return {
name,
age,
gender: undefined,
};
},
};
module.exports = fn;
```
```js
// fn.test.js
const fn = require("./fn");test("์ด๋ฆ๊ณผ ๋์ด๋ฅผ ์ ๋ฌ๋ฐ์์ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ค", () => {
expect(fn.makeUser("minjae", 27)).toEqual({
name: "minjae",
age: 27
});
});test("์ด๋ฆ๊ณผ ๋์ด๋ฅผ ์ ๋ฌ๋ฐ์์ ๊ฐ์ฒด๋ฅผ ๋ฐํํด์ค", () => {
expect(fn.makeUser("minjae", 27)).toStrictEqual({
name: "minjae",
age: 27
});
});
```
- ์ ์์ ์์ `toEqual`์ ํ ์คํธ๋ฅผ ํต๊ณผํ์ง๋ง `toStrictEqual`์ ํ ์คํธ๋ฅผ ํต๊ณผํ์ง ๋ชปํ๋ค. ์ฆ `toStrictEqual`์ ์ข ๋ ์๊ฒฉํ ํ ์คํธ ๋ฐฉ๋ฒ์ด๋ค.
- `toStrictEqual` ์์ ๊ฐ ํต๊ณผํ๋ ค๋ฉด gender ํค์ undefined ๊ฐ์ ์ถ๊ฐํ๋ฉด ๋๋ค.
### ๐โโ๏ธ 4. toBeNull, toBeUndefined, toBeDefined
```js
// fn.test.js
test("null์ null์ด๋ค.", () => {
expect(null).toBeNull();
});test("undefined๋ undefined์ด๋ค.", () => {
expect(undefined).toBeUndefined();
});test("x๋ ์ ์๋์ด ์๋ค.", () => {
const x = 1;
expect(x).toBeDefined();
});
```
- `toBeNull`์ null์ด๋ฉด ํ ์คํธ๊ฐ ํต๊ณผํ๋ค.
- `toBeUndefined`๋ ๊ฐ์ด undefined์ด๋ฉด ํต๊ณผํ๋ค.
- `toBeDefined`๋ ๊ฐ์ด ์ ์๋์ด ์์ผ๋ฉด ํต๊ณผํ๋ค.
### ๐โโ๏ธ 5. toBeTruthy, toBeFalsy
```js
// fn.test.js
//fn์ ์์ ์์ ์ฝ๋ ์ฐธ๊ณ
test("0์ false์ด๋ค.", () => {
expect(fn.add(1, -1)).toBeFalsy();
});test("1์ true์ด๋ค.", () => {
expect(fn.add(2, -1)).toBeTruthy();
});
```
- `toBeTruthy`์ ๊ฐ์ด true์ด๋ฉด ํ ์คํธ๊ฐ ํต๊ณผํ๋ค.
- `toBeFalsy`์ ๊ฐ์ด false์ด๋ฉด ํ ์คํธ๊ณผ ํต๊ณผํ๋ค.
### ๐โโ๏ธ 6. toBeGreaterThan, toBeGreaterThanOrEqual, toBeLessThan, toBeLessThanOrEqual
```js
// fn.test.js
test("ID๋ 10์ ์ดํ์ฌ์ผ ํฉ๋๋ค.", () => {
const id = "THE_BLACK";
expect(id.length).toBeGreaterThan(5);
});test("ID๋ 10์ ์ดํ์ฌ์ผ ํฉ๋๋ค.", () => {
const id = "THE_BLACK";
expect(id.length).toBeLessThanOrEqual(10);
});
```
- `toBeGreaterThan`์ ๊ฐ์ด ํฌ๋ฉด ํ ์คํธ๊ฐ ํต๊ณผํ๋ค.
- `toBeGreaterThanOrEqual`์ ๊ฐ์ด ํฌ๋ฉด ํ ์คํธ๊ฐ ํต๊ณผํ๋ค.
- `toBeLessThan`์ ๊ฐ์ด ์์ผ๋ฉด ํ ์คํธ๊ฐ ํต๊ณผํ๋ค.
- `toBeLessThanOrEqual`์ ๊ฐ์ด ์๊ฑฐ๋ ๊ฐ์ผ๋ฉด ํ ์คํธ๊ฐ ํต๊ณผํ๋ค.
### ๐โโ๏ธ 7. toBeCloseTo
```js
// fn.test.js
test("0.1๋ํ๊ธฐ 0.2๋ 0.3dlek.", () => {
expect(fn.add(0.1, 0.2)).toBeCloseTo(0.3);
});
```
- ์๋ฐ์คํฌ๋ฆฝํธ์์ 0.1 ๋ํ๊ธฐ 0.2๋ 0.3์ด ์๋๋ค. 0.300000000004์ด๋ค. ์ฆ, ์์์ ์ ์ ํํ๊ฒ ๊ณ์ฐํ์ง ๋ชปํ๋ค. ๊ทธ๋ ๊ธฐ ๋๋ฌธ์ `toBe`๋ `toEqual`์ ์ฌ์ฉํ๋ฉด ํ ์คํธ ํต๊ณผ๊ฐ ๋์ง ๋ชปํ๋ค.
- ์ด๋ด๋ ์ฌ์ฉํ๋ ๊ฒ `toBeCloseTo`์ด๋ค. `toBeCloseTo`๋ ๊ทผ์ฌ๊ฐ์ธ์ง ํ๋ณํด์ค๋ค.
### ๐โโ๏ธ 8. toMatch
```js
// fn.test.js
test("Hello World์ H๋ผ๋ ๊ธ์๊ฐ ์๋?", () => {
expect("Hello World").toMatch(/H/); // /H/ ๋ค์ i๋ฅผ ๋ถ์ด๋ฉด ๋์๋ฌธ์ ๊ตฌ๋ถ์ด ์์ด์ง๋ค.
});test("Hello World์ H๋ผ๋ ๊ธ์๊ฐ ์๋?", () => {
expect("Hello World").toMatch(/h/i); // /h/ ๋ค์ i๋ฅผ ๋ถ์ด๋ฉด ๋์๋ฌธ์ ๊ตฌ๋ถ์ด ์์ด์ง๋ค.
});
```
- `toMatch`๋ ๋ฌธ์์ด์ ํ๋ณํด์ค๋ค. ํฌํจ๋์ด ์์ผ๋ฉด ํ ์คํธ๊ฐ ํต๊ณผํ๋ค.
### ๐โโ๏ธ 9. toContain
```js
// fn.test.js
test("Hello World์ H๋ผ๋ ๊ธ์๊ฐ ์๋?", () => {
const user = "Mike";
const userList = ["Tom", "Mike", "Kai"];expect(userList).toContain(user);
});
```
- `toContain`๋ ๋ฐฐ์ด์์ ํน์ ์์๊ฐ ์๋์ง ํ๋ณํด์ค๋ค. ์์ผ๋ฉด ํ ์คํธ๊ฐ ํต๊ณผํ๋ค.
### ๐โโ๏ธ 10. toThrow
```js
const fn = {
// ...
throwErr: () => {
throw new Error("error");
},
};module.exports = fn;
```
```js
// fn.test.js
test("์ด๊ฑฐ ์๋ฌ๊ฐ ๋๋์?", () => {
expect(() => fn.throwErr()).toThrow();
});test("์ด๊ฑฐ ์๋ฌ๊ฐ ๋๋์?", () => {
expect(() => fn.throwErr()).toThrow("error");
});
```
- `throwErr`๋ ์๋ฌ๊ฐ ๋ฐ์ํ๋ฉด ํ ์คํธ๊ฐ ํต๊ณผ๋๋ค.
- ๋ง์ฝ `thThrow` ์ธ์๋ก ํน์ ์์๋ฅผ ๋ฃ์ผ๋ฉด ๋น๊ต๋ฅผํด์ ์ถ๋ ฅ๊ฐ๊ณผ ์ธ์๊ฐ ๊ฐ์ผ๋ฉด ํ ์คํธ๊ฐ ํต๊ณผํ๋ค.
## ๐ ๋น๋๊ธฐ ์ฝ๋ ํ ์คํธ
### ๐โโ๏ธ 1. ๊ธฐ๋ณธ ์์
```js
// fnAsync.js
const fnAsync = {
add: (num1, num2) => num1 + num2,
getName: (callback) => {
const name = "Mike";
setTimeout(() => {
callback(name);
}, 3000);
},
};module.exports = fnAsync;
```
```js
// fnAsync.test.js
test("3์ด ํ์ ๋ฐ์์จ ์ด๋ฆ์ Mike", () => {
const callback = (name) => {
expect(name).toBe("Mike");
};
fn.getName(callback);
});
```
- ์ ์์ ์ฒ๋ผ ์คํํ๋ฉด jest๋ ์ฝ๋ ๋์ ๋ค๋ค๋ฅด๋ฉด ๊ทธ๋ฅ ์ฝ๋๊ฐ ์ข ๋ฃ๋๋ค.
```js
// fnAsync.test.js
test("3์ด ํ์ ๋ฐ์์จ ์ด๋ฆ์ Mike", (done) => {
const callback = (name) => {
expect(name).toBe("Mike");
done();
};
fn.getName(callback);
});
```
- ์ ์์ ์ฒ๋ผ test ๋ฉ์๋์ ๋๋ฒ์งธ ํ๋ผ๋ฏธํฐ ์ฝ๋ฐฑํจ์์ ํ๋ผ๋ฏธํฐ๋ก `done`์ ๋ฃ๊ณ ์ด done์ด ํธ์ถ๋๋ฉด ์ข ๋ฃ๋๊ฒ๋ ์์ฑํ๋ฉด ์ ๋๋ก ๋น๋๊ธฐ ์ฝ๋ ํ ์คํธ๊ฐ ๊ฐ๋ฅํด์ง๋ค.
- ๋ง์ฝ `done`์ ํ๋ผ๋ฏธํฐ๋ก ๋ฃ๊ณ ์ฌ์ฉํ์ง ์์ผ๋ฉด ํ ์คํธ๋ ์คํจํ๊ฒ ๋๋ค.
### ๐โโ๏ธ 2. try/catch
```js
// fnAsync.test.js
test("3์ด ํ์ ๋ฐ์์จ ์ด๋ฆ์ Mike", (done) => {
const callback = (name) => {
try {
expect(name).toBe("Mike");
done();
} catch (e) {
done();
}
};
fn.getName(callback);
});
```
- ๋ง์ฝ API ์๋ฌ๋ฅผ ๊ฐ์งํ๊ณ ์ถ๋ค๋ฉด `try/catch`๋ฅผ ์ฌ์ฉํ๋ฉด ๋๋ค.
### ๐โโ๏ธ 3. Promise ํ์ ์ฒ๋ฆฌ ๋ฉ์๋
```js
// fnAsync.js
const fnAsync = {
// ...
getAge: () => {
const age = 27;
return new Promise((res, rej) => {
setTimeout(() => {
res(age);
// rej("error");
}, 3000);
});
},
};
module.exports = fnAsync;
```
```js
// fnAsync.test.js
test("3์ด ํ์ ๋ฐ์์จ ๋์ด๋ 27", () => {
return fn.getAge().then((age) => {
expect(age).toBe(27);
});
});// ์ ์์ ๋ณด๋ค ์ข ๋ ๊ฐ๊ฒฐํ resolves, rejects๋ฅผ ์ฌ์ฉํ ์ฝ๋
test("3์ด ํ์ ๋ฐ์์จ ๋์ด๋ 27", () => {
return expect(fn.getAge()).resolves.toBe(27);
});test("3์ด ํ์ ์๋ฌ๊ฐ ๋ฐ์ํฉ๋๋ค.", () => {
return expect(fn.getAge()).rejects.toMatch("error");
});
```
- Promise ์ฝ๋๋ฅผ ํ ์คํธํ ๋๋ `return`์ ๊ผญ ์ฌ์ฉํด์ผ ํ๋ค. ์๊ทธ๋ฌ๋ฉด ์ ๋๋ก ๋ ํ ์คํธ๊ฐ ๋ถ๊ฐ๋ฅ!
### ๐โโ๏ธ 4. async/await
```js
// fnAsync.test.js
test("3์ด ํ์ ๋ฐ์์จ ๋์ด๋ 27", async () => {
const age = await fn.getAge();
expect(age).toBe(30);
});test("3์ด ํ์ ๋ฐ์์จ ๋์ด๋ 27", async () => {
await expect(fn.getAge()).resolves.toBe(27);
});
```
## ๐ ํ ์คํธ ์ ํ ์์
### ๐โโ๏ธ 1. beforeEach
```js
let num = 0;
beforeEach(() => {
num = 0;
});
test("0 ๋ํ๊ธฐ 1์ 1์ด์ผ", () => {
num = fn.add(num, 1);
expect(num).toBe(1);
});
```
- beforeEach๋ ๊ฐ ํ ์คํธ๊ฐ ์คํํ ๋๋ง๋ค ์คํ๋๋ ํจ์์ด๋ค.
### ๐โโ๏ธ 2. afterEach
```js
let num = 0;
afterEach(() => {
num = 0;
});
test("0 ๋ํ๊ธฐ 1์ 1์ด์ผ", () => {
num = fn.add(num, 1);
expect(num).toBe(1);
});
```
- afterEach๋ ๊ฐ ํ ์คํธ๊ฐ ์ข ๋ฃํ ๋๋ง๋ค ์คํ๋๋ ํจ์์ด๋ค.
### ๐โโ๏ธ 3. beforeAll/afterAll
```js
beforeAll(async () => {
user = await fn.connectUserDB();
});
afterAll(() => {
return fn.disconnectDB;
});
```
- beforeAll์ ์ ์ฒด ํ ์คํธ๋ฅผ ๊ธฐ์ค์ผ๋ก ์ฒ์ ํ ์คํธ๊ฐ ์คํํ ๋ ์คํ๋๋ค.
- afterAll์ ์ ์ฒด ํ ์คํธ๋ฅผ ๊ธฐ์ค์ผ๋ก ํ ์คํธ๊ฐ ๋ชจ๋ ์ข ๋ฃ๋ ๋ ์คํ๋๋ค.
- db์ฐ๊ฒฐ์ด๋ ์ข ๋ฃ๋ ์ฒ์๊ณผ ๋์๋ง ์คํ๋๋ฉด๋์ ๋งค๋ฒ ์คํ๋๋ beforeEach๋ afterEach๋ฅผ ์ฌ์ฉํ๊ธฐ ๋ณด๋ค๋ beforeAll, afterAll์ ์ฌ์ฉํ๋ ๊ฒ์ด ์ข๋ค.
### ๐โโ๏ธ 4. describe
```js
describe("Car ๊ด๋ จ ์์ ", () => {
let car = {};beforeAll(async () => {
car = await fn.connectCarDB();
});
afterAll(() => {
return fn.disconnectCarDB;
});test("์ด๋ฆ์ Minjae", () => {
expect(car.brend).toBe("bmw");
});
test("๋์ด๋ 27", () => {
expect(car.name).toBe("z4");
});
test("์ด๋ฆ์ Minjae", () => {
expect(car.color).toBe("red");
});
});
```
- describe๋ ํ ์คํธ ํ์ผ์ ๋ง์ ์์ ํ ์คํธ ํจ์๊ฐ ์์ฑ๋ ๊ฒฝ์ฐ, ์ฐ๊ด๋ ํ ์คํธ ํจ์๋ค๋ผ๋ฆฌ ๊ทธ๋ฃนํํ๋ ํจ์์ด๋ค.
- describe๋ฅผ ์ฌ์ฉํ ๋ testํจ์ ๋์ `it`ํจ์๋ฅผ ์ฌ์ฉํ๊ธฐ๋ ํ๋๋ฐ, ์ด ๋ ํจ์๋ ์์ ํ ๋์ผํ ๊ธฐ๋ฅ์ ํ๋ ํจ์์ด๋ค. Mocha๋ Jasmin ๊ฐ์ ํ ์คํธ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์์ ํจ์๋ช ์ it์ ์ฌ์ฉํ๊ธฐ ๋๋ฌธ์ Jest์์๋ it์ test ํจ์์ ๋ณ์นญ์ผ๋ก ์ ๊ณตํ๋ค.
### ๐โโ๏ธ 4. only/skip
```js
test.only("0๋ํ๊ธฐ 5์ 5์ผ", () => {
expect(fn.add(num, 3)).toBe(5);
});
test.skip("0๋ํ๊ธฐ 5์ 5์ผ", () => {
expect(fn.add(num, 3)).toBe(5);
});```
- only์ skip์ ํ ์คํธ ์ฝ๋๋ฅผ ๋๋ฒ๊น ํ ๋ ์ ์ฉํ๊ฒ ์ฌ์ฉํ๋ค.
- only๋ ํ ์คํธ ํ์ผ์์ ํ ์คํธ ํจ์๊ฐ ๋ง์๋ฐ ๊ทธ ์ค์์ ํ๋๋ง ์คํจํ์ ๊ฒฝ์ฐ, ๊ทธ ํจ์๋ง ๋จ๋ ์ผ๋ก ์คํํด๋ณด๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
- skip์ only์ ๋ฐ๋๋ก ์๋ํ๋ค. ์ด๋ค ํจ์๋ง ๋นผ๊ณ ์คํํด๋ณด๊ณ ์ถ์ ๋ ์ฌ์ฉํ๋ค.
## ๐ ์คํ ์์
```js
beforeAll(() => console.log("๋ฐ beforeAll")); // 1
beforeEach(() => console.log("๋ฐ beforeEach")); // 2, 6
afterAll(() => console.log("๋ฐ afterAll")); // 4, 10
afterEach(() => console.log("๋ฐ afterEach")); // ๋ง์ง๋งtest("2๋ํ๊ธฐ 3์ 5์ผ", () => {
expect(fn.add(2, 3)).toBe(5); // 3
});describe("Car ๊ด๋ จ ์์ ", () => {
beforeAll(() => console.log("๋ฐ beforeAll")); // 5
beforeEach(() => console.log("๋ฐ beforeEach")); // 7
afterAll(() => console.log("๋ฐ afterAll")); // 9
afterEach(() => console.log("๋ฐ afterEach")); // ๋ง์ง๋ง-1test("2๋ํ๊ธฐ 3์ 5์ผ", () => {
expect(fn.add(2, 3)).toBe(5); // 8
});
});
```
## ๐ Mockup
### ๐โโ๏ธ 1. mockFn.mock.calls
```js
//fnMock.test.js
const mockFn = jest.fn();function forEachAdd1(arr) {
arr.forEach((num) => {
mockFn(num + 1);
});
}forEachAdd1([10, 20, 30]);
test("ํจ์๋ 3๋ฒ ํธ์ถ๋๋ค.", () => {
expect(mockFn.mock.calls.length).toBe(3);
});test("์ ๋ฌ๋ ๊ฐ์ 11, 21, 31์ด๋ค.", () => {
expect(mockFn.mock.calls[0][0]).toBe(11);
expect(mockFn.mock.calls[1][0]).toBe(21);
expect(mockFn.mock.calls[2][0]).toBe(31);
});console.log(mockFn.mock.calls); // [[11], [21], [31]]
```
- mockFn.mock.calls์๋ ์ธ์๋ก ๋ฐ์์จ ๊ฐ๋ค๊ณผ ๊ธธ์ด๋ฅผ ์ ์ ์๋ค.
### ๐โโ๏ธ 2. mockFn.mock.results
```js
const mockFn = jest.fn((num) => num + 1);mockFn(10);
mockFn(20);
mockFn(30);test("10์์ 1์ฆ๊ฐํ ๊ฐ์ด ๋ฐํ๋๋ค.", () => {
expect(mockFn.mock.results[0].value).toBe(11);
});test("20์์ 1์ฆ๊ฐํ ๊ฐ์ด ๋ฐํ๋๋ค.", () => {
expect(mockFn.mock.results[1].value).toBe(21);
});test("30์์ 1์ฆ๊ฐํ ๊ฐ์ด ๋ฐํ๋๋ค.", () => {
expect(mockFn.mock.results[2].value).toBe(31);
});console.log(mockFn.mock.results);
/*
[
{ type: 'return', value: 11 },
{ type: 'return', value: 21 },
{ type: 'return', value: 31 }
]
*/
```
- mockFn.mock.results๋ ๋ฆฌํด๊ฐ์ ํ์ธํ ์ ์๋ค.
### ๐โโ๏ธ 3. mockReturnValueOnce/mockReturnValue
```js
const mockFn = jest.fn();mockFn.mockReturnValueOnce(10)
.mockReturnValueOnce(20)
.mockReturnValueOnce(30)
.mockReturnValue(40);
mockFn();
mockFn();
mockFn();
mockFn();test("dd", () => {
expect("dd").toBe("dd");
});console.log(mockFn.mock.results);
/*
[
{ type: 'return', value: 10 },
{ type: 'return', value: 20 },
{ type: 'return', value: 30 },
{ type: 'return', value: 40 }
]
*/
```
- mockReturnValueOnce๋ฅผ ์ฌ์ฉํ๋ฉด mockFn์ด ์คํ๋ ๋๋ง๋ค ๋ค๋ฅธ ๊ฐ์ ๋ฆฌํด์ด ๊ฐ๋ฅํ๋ค. ๋ง์ง๋ง์๋ Once๋ฅผ ์๋ตํ๋ค.
### ๐โโ๏ธ 4. mockResolvedValue
```js
const mockFn = jest.fn();mockFn.mockResolvedValue({ name: "Mike" });
test("๋ฐ์์จ ์ด๋ฆ์ Mike", () => {
mockFn().then((res) => {
expect(res.name).toBe("Mike");
});
});
```
- mockResolvedValue๋ฅผ ์ด์ฉํด์ ๋น๋๊ธฐ ํจ์๋ฅผ ํ ์คํธํด๋ณผ ์๋ ์๋ค.
### ๐โโ๏ธ 5. mockReturnValue
```js
const fn = require("../fnAsync");jest.mock("../fnAsync");
fn.createUser.mockReturnValue({ name: "Mike" });
test("์ ์ ๋ฅผ ๋ง๋ ๋ค.", () => {
const user = fn.createUser("Mike");
expect(user.name).toBe("Mike");
});
```
- ๋ง์ฝ db์ ์ ๋ฅผ ์์ฑํ๋ ํ ์คํธ ์ฝ๋๋ฅผ ์คํํ ๋ ์ค์ ๋ก db์ ์ ์ ๊ฐ ์์ฑ๋๋ฉด ์๋๊ธฐ ๋๋ฌธ์, `mockReturnValue`๋ฅผ ์ด์ฉํด์ ์ค์ createUser๊ฐ ์คํ๋์ง์๊ณ Mock ํจ์๋ง ์คํ๋๊ฒ๋ ํ ์ ์๋ค.
### ๐โโ๏ธ 6. toBeCalled, toBeCalledTimes, toBeCalledWith, lastCalledWith
```js
const mockFn = jest.fn();mockFn(10, 20);
mockFn();
mockFn(30, 40);test("ํ๋ฒ ์ด์ ํธ์ถ?", () => {
expect(mockFn).toBeCalled();
});
test("์ ํํ ์ธ๋ฒ ํธ์ถ?", () => {
expect(mockFn).toBeCalledTimes(3);
});
test("10์ด๋ 20 ์ ๋ฌ๋ฐ์ ํจ์ ์์?", () => {
expect(mockFn).toBeCalledWith(10, 20);
});
test("๋ง์ง๋ง ํจ์๋ 30์ด๋ 40๋ฐ์?", () => {
expect(mockFn).lastCalledWith(30, 40);
});
```
- toBeCalled๋ ํ๋ฒ ์ด์ ํธ์ถ๋ฌ์ผ๋ฉด ํ ์คํธ๊ฐ ํต๊ณผ๋๋ค.
- toBeCalledTimes๋ ์ ํํ๊ฒ ํธ์ถ ํ์๊ฐ ๋ง์ผ๋ฉด ํ ์คํธ๊ฐ ํต๊ณผ๋๋ค.
- toBeCalledWith๋ ์ธ์๋ก ์ด๋ค ๊ฐ์ ๋ฐ์๋์ง ์ฒดํฌํ๋ค.
- lastCalledWith๋ toBeCalledWith๋์ฒ๋ผ ์ธ์๋ก ์ด๋ค ๊ฐ์ ๋ฐ์๋์ง ์ฒดํฌํ์ง๋ง ๋งจ ๋ง์ง๋ง์ผ๋ก ํธ์ถ ๋ ํจ์๋ง ์ฒดํฌํ๋ค.
## ๐ React Components
- React Testing Library๋ ๋งค์ฐ ์ฌํํ์ง๋ง ๊ฐ๋ ฅํ API๋ฅผ ๊ฐ๊ณ ์๋ค.
- DOM์ปดํฌ๋ํธ๋ฅผ ๋๋๋งํด์ฃผ๋ render() ํจ์์, ํน์ ์ด๋ฒคํธ๋ฅผ ๋ฐ์์์ผ์ฃผ๋ fireEvent ๊ฐ์ฒด, ๊ทธ๋ฆฌ๊ณ DOM์์ ํน์ ์์ญ์ ์ ํํ๊ธฐ ์ํ ๋ค์ํ ์ฟผ๋ฆฌ ํจ์๋ค์ด ์กด์ฌํ๋ค.```js
import { render, fireEvent, screen } from "@testing-library/react";
```
- `@testing-library/react` ๋ชจ๋๋ก ๋ถํฐ ๋ฐ๋ก import๊ฐ ๊ฐ๋ฅํ๋ค.
### ๐โโ๏ธ 1. toBeInTheDocument()
```js
const user = {
name: "Tom",
age: 27,
};test("Hello ๋ผ๋ ๊ธ์๊ฐ ํฌํจ๋๋๊ฐ?", () => {
render();
const helloEl = screen.getByText(/Hello/i);
expect(helloEl).toBeInTheDocument();
});
```
- getByText๋ ํ ์คํธ๋ฅผ ๊ฒ์ฌํ๋ค.
- toBeInTheDocument๋ ๊ฒ์ฌํ๋ ค๋ ์์๊ฐ ๋ฌธ์์ ์๋์ง ์ฌ๋ถ๋ฅผ ํ์ธํ๊ธฐ ์ํ ๋ฉ์๋์ด๋ค.
### ๐โโ๏ธ 2. toMatchSnapshot
```js
const user = {
name: "Tom",
age: 27,
};const user2 = {
age: 30,
};test("snapshot: name์์", () => {
const el = render();
expect(el).toMatchSnapshot();
});test("snapshot: name์์", () => {
const el = render();
expect(el).toMatchSnapshot();
});
```
- ์ค๋ ์ท ํ ์คํ (Snapshot testing)์ด๋ ์ด๋ค ๊ธฐ๋ฅ์ ์์ ๊ฒฐ๊ณผ๋ฅผ ๋ฏธ๋ฆฌ ์ ํํ ํฌ์ฐฉํด๋๊ณ ์ค์ ๊ฒฐ๊ณผ์ ๋น๊ตํ๋ ํ ์คํธ ๊ธฐ๋ฒ์ด๋ค.
- ํ ์คํธ ๋์ ๊ธฐ๋ฅ์ ๊ตฌํ์ด ๋ณ๊ฒฝ๋์ด ์ค์ ๊ฒฐ๊ณผ๊ฐ ์ค๋ ์ท์ ๋ ๋์ ์์ ๊ฒฐ๊ณผ์ ๋ฌ๋ผ์ง ๊ฒฝ์ฐ ํด๋น ํ ์คํธ ์ผ์ด์ค๋ ์คํจํ๊ฒ ๋๋ค.
- ์ด๋ฌํ ๊ฒฝ์ฐ ๋ค์ ์๋ก์ด ์ค๋ ์ท์ ๋ ์ ๊ธฐ์กด ์ค๋ ์ท์ ๊ต์ฒดํ๋ ๋ฐฉ์์ผ๋ก ํ ์คํธ ์ฝ๋์ ํจ๊ป ์ค๋ ์ท๋ ํจ๊ป ์ ์ง๋ณด์๋ฅผ ํ๋ค.
- Jest์์๋ ํ์ผ ์ค๋ ์ท ํ ์คํ ์ ์ง์ํ๊ธฐ ์ํด์ `toMatchSnapshot()`์ด๋ผ๋ ํจ์๋ฅผ ์ ๊ณตํ๋ค.
### ๐โโ๏ธ 3. Mockup
```js
test("์ด ํ์", () => {
Date.now = jest.fn(() => 123456789);
const el = render();
expect(el).toMatchSnapshot();
});
```
- ์๊ฐ์ฒ๋ผ ๋งค๋ฒ ๊ฐ์ด ๋ฐ๊ปด์ ํ ์คํธ๋ฅผ ํ ๋๋ง๋ค ์ค๋ฅ๊ฐ ๋ฐ์ํ๋ ๋ถ๋ถ์ mockํจ์๋ฅผ ์ด์ฉํด์ ๊ณ ์ ๊ฐ์ ์ฃผ๋ฉด ๋๋ค.