λͺ¨νΉμ΄λ?
κΈ°μ‘΄ ν¨μμ κΈ°λ₯μ νλ΄λ΄λ κ°μ§ ν¨μλ₯Ό λ§λ€μ΄ λ΄λ κ²μ λ§νλ€.
μ°λ¦¬κ° ν μ€νΈ μ½λλ₯Ό μμ±ν λ λ°μ΄ν°λ² μ΄μ€λ μΈλΆμ μλ²λ‘λΆν° λ°μ΄ν°λ₯Ό κ°μ Έμ€λ λ±μ μΈλΆμ μμ‘΄ν΄μΌ νλ κ²½μ°κ° μλ€. μ΄λ° κ²½μ°μλ λ¨μ ν μ€νΈκ° μΈλΆμ μν©μ λ°λΌμ κ²°κ³Όκ° λ¬λΌμ§λ λ¬Έμ μ μ΄ λ°μνκΈ° λλ¬Έμ μΈλΆμ μμ‘΄νλ μ½λλ₯Ό κ°μ§λ‘ λ체νλ λͺ¨νΉμ νμ©ν μ μλ€.
Jest
μμ λͺ¨νΉμ νμ©νλ λ°©λ²μ jest.fn()
, jest.spyOn()
, jest.mock()
μ΄ μλ€.
μ€ν νκ²½ μΆμ
λͺ¨νΉ ν¨μλ λ΄λΆμ μΌλ‘ .mock
νλ‘νΌν°λ₯Ό κ°μ§κ³ μλ€.
μ΄ νλ‘νΌν°μ λ€μ΄μλ μ¬λ¬ μμ±λ€μ ν΅ν΄μ λͺ¨νΉ ν¨μκ° λͺ λ² νΈμΆ λμλμ§, μ΄λ€ κ°μ μΈμλ‘ μ λ¬ λ°μλμ§, thisμ κ°μ 무μμ΄μλμ§ λ±μ λ€μν μ 보λ₯Ό μΆμ ν μ μλ€.
mockFn.mock.calls
λͺ¨νΉ ν¨μμ μ λ¬νλ μΈμμ μ 보λ₯Ό κΈ°μ΅νλ λ°°μ΄ λ³μμ΄λ€. λ§μ½ λͺ¨νΉ ν¨μλ₯Ό νΈμΆν λ f('arg1', 'arg2')
, f('arg3', 'arg4')
μ μμλ‘ μ§ννλ€λ©΄ λ΄λΆμ λ΄μ©μ λ€μκ³Ό κ°λ€:
[
['arg1', 'arg2'],
['arg3', 'arg4'],
];
mockFn.mock.results
λͺ¨νΉ ν¨μκ° λ°ννλ κ°μ κΈ°μ΅νλ κ°μ²΄κ° λ΄κΈ΄ λ°°μ΄ λ³μμ΄λ€. κ°μ²΄ λ΄λΆμλ type
κ³Ό value
κ°μ ν¬ν¨νκ³ μλ€.
Type μ’ λ₯
- return: λͺ¨νΉ ν¨μκ° κ°μ μ μμ μΌλ‘ λ°ννλ κ²½μ°μ΄λ€.
- throw: λͺ¨νΉ ν¨μκ° μμΈλ₯Ό λμ‘λ κ²½μ°μ΄λ€.
- imcomplete: μμ§ νΈμΆμ λν μ€νμ΄ μλ£λμ§ μμ κ²½μ°μ΄λ€.
[
{
type: 'return',
value: 'result1',
},
{
type: 'throw',
value: {
/* Error instance */
},
},
{
type: 'return',
value: 'result2',
},
];
mockFn.mock.instances
λͺ¨νΉ ν¨μκ° new
μ°μ°μλ‘ μΈμ€ν΄μ€ν λ κ²½μ°μ ν΄λΉ κ°μ²΄μ μΈμ€ν΄μ€κ° λ΄κΈ΄ λ°°μ΄ λ³μμ΄λ€.
const mockFn = jest.fn();
const a = new mockFn();
const b = new mockFn();
mockFn.mock.instances[0] === a; // true
mockFn.mock.instances[1] === b; // true
mockFn.mock.contexts
λͺ¨νΉ ν¨μλ₯Ό νΈμΆνλ λΉμμ this
μ λ°μΈλ©λλ κ°μ²΄ μ λ³΄κ° λ΄κΈ΄ λ°°μ΄ λ³μμ΄λ€.
describe('mock.contexts μ λν μ½λ', () => {
const mockFn = jest.fn();
class Person {
name: string;
age: number;
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
callMockFn(...args: any[]) {
mockFn.call(this, ...args);
}
}
const kim = new Person('kim', 20)
kim.callMockFn('a', 'b');
kim.callMockFn(10, 20);
const lee = new Person('lee', 25);
lee.callMockFn('a', 'b');
lee.callMockFn(10, 20);
test('νΈμΆνλ λΉμμ this κ° ν
μ€νΈ', () => {
expect(mockFn.mock.contexts[0]).toStrictEqual(kim); // true
expect(mockFn.mock.contexts[1]).toStrictEqual(kim); // true
expect(mockFn.mock.contexts[2]).toStrictEqual(lee); // true
expect(mockFn.mock.contexts[3]).toStrictEqual(lee); // true
});
});
// mockFn.mock.contexts
[
Person { name: 'kim', age: 20 },
Person { name: 'kim', age: 20 },
Person { name: 'lee', age: 25 },
Person { name: 'lee', age: 25 }
]
μ μ©ν Matcher
λͺ¨νΉ ν¨μμ λν μ€ν νκ²½μ μΆμ νκΈ° μν΄μ .mock
νλ‘νΌν°λ₯Ό μ§μ μ°Έμ‘°νμ§ μκ³ expect()
ν¨μμ Matcher
λ₯Ό μ΄μ©νλ λ°©λ²λ μλ€.
- .toHaveBeenCalled()
ν¨μκ° νΈμΆλ μ μ΄ μλμ§λ₯Ό νμΈνλ€.
.toBeCalled()
λ‘ μ¬μ©ν μλ μλ€. - .toHaveBeenCalledTimes(number)
ν¨μκ° νΉμ νμλ§νΌ νΈμΆλμλμ§λ₯Ό νμΈνλ€.
.toBeCalledTimes(number)
λ‘ μ¬μ©ν μλ μλ€. - .toHaveBeenCalledWith(arg1, arg2, ...)
ν¨μκ° ν΄λΉ μΈμλ₯Ό μ λ¬λ°κ³ νΈμΆλμλμ§λ₯Ό νμΈνλ€.
.toBeCalledWith()
λ‘ μ¬μ©ν μλ μλ€. - .toHaveReturned()
ν¨μκ° κ°μ λ°νν μ μ΄ μλμ§λ₯Ό νμΈνλ€.
.toReturn()
λ‘ μ¬μ©ν μλ μλ€. - .toHaveReturnedTimes(number)
ν¨μκ° νΉμ νμλ§νΌ λ°νλμλμ§λ₯Ό νμΈνλ€.
.toReturnTimes(number)
λ‘ μ¬μ©ν μλ μλ€. - .toHaveReturnedWith(value)
ν¨μκ° ν΄λΉ κ°μ λ°νν μ μ΄ μλμ§λ₯Ό νμΈνλ€.
.toReturnWith(value)
λ‘ μ¬μ©ν μλ μλ€.
jest.fn()
jest.fn()
μ νΈμΆνλ©΄ λͺ¨νΉ ν¨μκ° μμ±λλ€.
λͺ¨νΉ ν¨μλ₯Ό μμ±ν λ€μλ κ·Έ ν¨μκ° μ΄λ€ κ°μ λ°νν κ²μΈμ§λ₯Ό μ μν΄μ€μΌ νλλ° λ€μκ³Ό κ°μ APIκ° μ‘΄μ¬νλ€:
- mockFn.mockReturnValue(value)
λͺ¨νΉ ν¨μκ°value
λ₯Ό λ°ννλλ‘ νλ€. - mockFn.mockImplementation(fn)
λͺ¨νΉ ν¨μμ λ΄λΆμμ λμνλ μ½λλ₯Ό μ§μ μμ±νλ€. - mockFn.mockResolvedValue(value)
λͺ¨νΉ ν¨μκ° ν΄λΉvalue
λ₯Ό μ΄ννλPromise
λ₯Ό λ°ννλ€. - mockFn.mockRejectedValue(value)
λͺ¨νΉ ν¨μκ° ν΄λΉvalue
λ₯Ό μ΄μ λ‘ κ±°λΆνλPromise
λ₯Ό λ°ννλ€.
κ°κ°μ APIμλ mockFn.mockReturnValueOnce(value)
μ κ°μ΄ Once
κ° μ λ―Έμ¬λ‘ λΆμ κ²λ μ 곡νλλ°, μ΄λ μ΄νμ νΈμΆμ λν΄μ ν λ²λ§ μλνλ APIμ΄λ€.
μμ μ½λ
test('mocking', async () => {
const mockFn = jest
.fn()
.mockReturnValue('default')
.mockReturnValueOnce(5)
.mockImplementationOnce(() => 'hello')
.mockResolvedValueOnce('Resolved')
.mockRejectedValueOnce(new Error('Rejected'));
console.log(mockFn()); // 5
console.log(mockFn()); // 'hello'
console.log(mockFn()); // Promise { 'Resolved' }
console.log(mockFn()); // Promise { <rejected> Error: Rejected }
console.log(mockFn()); // 'default'
expect(mockFn()).toBe('default');
});
μ λ€λ¦
νμ
μ€ν¬λ¦½νΈλ₯Ό μ¬μ©νλ©΄ jest.fn()
μ μ λ€λ¦ μΈμλ₯Ό μΈ κ° λκ²¨μ€ μ μλ€.
function fn<T, Y extends any[], C = any>(implementation?: (this: C, ...args: Y) => T): Mock<T, Y, C>;
- T: ν΄λΉ λͺ¨νΉ ν¨μκ° λ°ννλ κ°μ νμ μ μ§μ νλ€.
- Y: ν΄λΉ λͺ¨νΉ ν¨μκ° λ°λ λ§€κ°λ³μμ νμ μ μ§μ νλ€.
- C: μ ννκ²λ λͺ¨λ₯΄κ² μ§λ§,
this
μ λ°μΈλ© λλ κ°μ νμ μ μ§μ νλ λ― νλ€.
μμ μ½λ
λ€μμ number
ννμ μΈμ λ κ°λ₯Ό λ°μμ ν©μ λ°ννλ μ½λμ΄λ€:
test('1 + 2 = 3', () => {
const adder = jest.fn<number, [number, number]>((a, b) => a + b);
expect(adder(1, 2)).toBe(3);
});
jest.spyOn()
μ€ν νκ²½μ μΆμ νλ κΈ°λ₯μ λͺ¨νΉ ν¨μμλ§ μ μ©μ΄ λλ€.
κ·Έλ κΈ° λλ¬Έμ μ€μ ꡬν μ½λμ ν¨μ μ체μ λν΄μλ μ€ν νκ²½μ μΆμ ν μ μλλ°, κ°νΉ ν¨μμ κΈ°λ₯μ νλ΄λ΄λ μλ‘μ΄ κ°μ§ ν¨μλ₯Ό λ§λλ κ²μ΄ μλλΌ κΈ°μ‘΄μ ν¨μλ₯Ό κ·Έλλ‘ μ¬μ©ν μ±λ‘ μ€ν νκ²½λ§ μΆμ νκ³ μΆμ κ²½μ°κ° μλ€.
μ΄λ° κ²½μ°μλ jest.spyOn()
μΌλ‘ κΈ°μ‘΄μ μ‘΄μ¬νλ κ°μ²΄μ μΌλΆ λ©μλκ° νΈμΆλλ νκ²½μ μ§μΌλ³΄λ λͺ¨νΉ ν¨μλ₯Ό λ§λ€ μ μλ€.
μμ μ½λ
μλ μ½λλ κΈ°μ‘΄ κ°μ²΄ calculator
μ add
λ©μλκ° λμνλ κ²μ μ§μΌλ³΄λ μ½λμ΄λ€.
describe('about spyon', () => {
const calculator = {
add: (a: number, b: number) => a + b,
minus: (a: number, b: number) => a - b
}
test('toHaveReturnedWith', () => {
const spy = jest.spyOn(calculator, 'add'); // calculator κ°μ²΄μ add λ©μλμ λμμ μ§μΌλ³Έλ€.
calculator.add(1, 2); // λͺ¨νΉ ν¨μλ₯Ό μ€ννλκ² μλλΌ, κΈ°μ‘΄μ ν¨μλ₯Ό κ·Έλλ‘ μ€ννκ³ μλ€.
calculator.add(3, 2);
calculator.add(5, 4);
expect(spy).toHaveReturnedWith(3);
});
});
jest.mock()
νΉμ λͺ¨λμ λͺ¨νΉνλ κΈ°λ₯μ΄λ€.
ν
μ€νΈ νλ €λ μ½λμμ λͺ¨νΉν΄μΌ νλ λΆλΆμ΄ λ§λ€λ©΄ μΌμΌν jest.fn()
μΌλ‘ μλ‘μ΄ λͺ¨νΉ ν¨μλ₯Ό λ§λλ κ³Όμ λ κ΅μ₯ν λ²κ±°λ‘μμ§λ€.
νΉν axios
κ°μ΄ μΈλΆ λΌμ΄λΈλ¬λ¦¬μ μμ‘΄νλ λΆλΆμ λν λͺ¨νΉμ μ²λ¦¬ν΄μΌ νλ κ²½μ°μ μ΄λ €μμ΄ λν΄μ§λλ° jest.mock()
μ μ΄μ©νλ©΄ νΉμ λͺ¨λμ νλ²μ λͺ¨νΉν μ μλ€.
μ¬μ© λ°©λ²μ μ΅μμ λ 벨μ μμμμ jest.mock(μ¬μ©ν λͺ¨λ)
μ νΈμΆν΄μ£Όλ©΄ λλ€.
μ§μ λ§λ messageService
μ μΈλΆ λΌμ΄λΈλ¬λ¦¬μΈ axios
μμ λ΄λ³΄λ΄λ λͺ¨λ ν¨μμ λν΄μ λͺ¨νΉνκ³ μΆλ€λ©΄ λ€μκ³Ό κ°μ΄ μμ±νλ€:
jest.mock('../messageService');
jest.mock('axios');
μ°Έκ³ μλ£
Mock Functions
Mock Functions API
jest.fn(), jest.spyOn() ν¨μ λͺ¨νΉ (DaleSeo)
λͺ¨νΉ Mocking μ 리 - jest.fn / jest.mock / jest.spyOn (Inpa)