π ν μ€νΈ μ½λλ₯Ό λΆμνλ μ΄μ
λ¬Έμ λ₯Ό νμ΄λ΄κΈ° μν΄μλ κ·Έ λ¬Έμ μμ μꡬνλ λ°λ₯Ό μ νν μμμΌ νκΈ° λλ¬Έμ΄λ€. μ΅μ’ μ½λ© ν μ€νΈ λ κΈ°λ₯ μꡬ μ¬νκ³Ό λλΆμ΄, ν μ€νΈ μ½λμμ μꡬνλ λ°λ₯Ό μ ννκ³ λΉ λ₯΄κ² μκ³ μ μ½λλ₯Ό μ μ μ΄ νν€μ³λ³΄κ³ μ νλ€. λ λμκ°, μμΌλ‘ λ¨μ ν μ€νΈλΏλ§ μλλΌ μ§μ μ ν리μΌμ΄μ μ½λλ μ§λ³΄κ³ μΆμλ€.
ν리μ½μ€ κΈ°κ°μλ 'κ·Έλ ꡬλ~' νκ³ λκ²Όλ ν μ€νΈ μ½λλ₯Ό ν리μ½μ€ μ’ λ£ νμ μκ°μ λ΄μ΄ κΉκ² ν보μλ€. λλΆμ΄, Jestλ ν μ€νΈ μ½λ κ΄λ ¨ κ°λ λ ν¨κ» 곡λΆν΄ 보μλ€. μ°Έκ³ λ‘ μ 체 ν μ€νΈ μ½λλ μ°μνν ν¬μ½μ€ repoμμλ λ³Ό μ μλ€.
1οΈβ£ μμ! μΌλ¨ λΆλ¬μ€κΈ°
// App μ»΄ν¬λνΈλ₯Ό λΆλ¬μ΄
import App from '../src/App.js';
// @woowacourse/mission-utils λΌμ΄λΈλ¬λ¦¬μμ MissionUtils κ°μ²΄λ₯Ό λΆλ¬μ΄
import { MissionUtils } from '@woowacourse/mission-utils';
μ°μ , ν μ€νΈνκ³ μ νλ μ»΄ν¬λνΈλ₯Ό λΆλ¬μ€κ³ , μ°ν μ½μμ μ 곡νλ λΌμ΄λΈλ¬λ¦¬μμ MissionUtilsλΌλ κ°μ²΄λ₯Ό λΆλ¬μ¨λ€.
2οΈβ£ μ¬μ©μ μ λ ₯κ°μ λν΄ ν μ€νΈνκΈ° - mock μ΄λ?
μ΄ ν μ€νΈλ λ¨μν 'νλμ λ©μλκ° μ μλνλλ'λ₯Ό κ²μ¦νλ κ²μ΄ μλλΌ, μ¬μ©μκ° μΈνμ λ£μμ λ κ·Έμ λ§λ μμνμ΄ λμ€λμ§λ₯Ό κ²μ¦νλ κ²μ΄λ€. κ·Έλ°λ° μ¬κΈ°μ μ¬μ©μμ μΈνμ μ΄λ»κ² λ§λ€κΉ?
λ°λ‘ 'λͺ¨μ(mock)'νλ λ°©λ²μ΄ μλ€. μ¦, νλ΄ λ΄μ΄ μ€μ μ²λΌ ν΄λ³΄λ κ²μ΄λ€.
λͺ¨μ ν¨μλ₯Ό μ¬μ©νλ©΄ ν¨μμ μ€μ ꡬνμ μμ νκ³ , μ½λ κ°μ μνΈ μμ©μ μ½κ² ν μ€νΈν μ μμ΅λλ€. mock ν¨μλ₯Ό μ¬μ©νλ©΄ νΈμΆ μ ν¨μμ μ λ¬λλ μΈμμ ν¨κ» newλ₯Ό ν΅ν΄ μμ±ν λ μΈμ€ν΄μ€λ *μΊ‘μ²ν μ μμΌλ©°, ν μ€νΈ κ³Όμ μ€ return κ°μ μ€μ ν μ μμ΅λλ€. (μ°Έκ³ : Jest 곡μλ¬Έμ Mock Functions)
βͺοΈ μ¬κΈ°μ λ§νλ *μΊ‘μ²λ Jest 곡μλ¬Έμ λ²μ λ§ν¬λΌ μ΄ν΄κ° μ΄λ €μΈ μ μλ€. μ½κ² νμ΄ λ§νμλ©΄ ν¨μκ° νΈμΆλ λ κ·Έ ν¨μμ μ λ¬λλ μΈμλ€μ κΈ°λ‘νκ³ , λμ€μ μ΄ μΈμλ€μ κ²μ¬ν μ μκ² νλ κ²μ μλ―Ένλ€κ³ 보면 λλ€.
Jestμμ λͺ¨μ ν¨μλ₯Ό μ¬μ©νλ©΄ ν΄λΉ ν¨μμ μ€μ ꡬνμ λ체νκ³ , ν¨μ νΈμΆκ³Ό κ·Έ νΈμΆμ μ¬μ©λ μΈμλ€μ μΆμ νλ€. μ΄λ₯Ό ν΅ν΄ κ°λ°μλ ν¨μκ° μμλλ‘ νΈμΆλμλμ§, μ¬λ°λ₯Έ μΈμλ€μ΄ μ λ¬λμλμ§ λ±μ ν μ€νΈ μ½λ λ΄μμ νμΈν μ μλ€.
μ«μμΌκ΅¬ ν μ€νΈ μ½λμμλ μλμ κ°μ΄ μ λ ₯κ°μ λͺ¨μνλ mockQuestions ν¨μλ₯Ό λ¨Όμ μ μνλ€.
// μ
λ ₯κ°μ λͺ¨μνλ ν¨μλ₯Ό μ μ
const mockQuestions = (inputs) => {
// MissionUtils.Console.readLineAsync ν¨μλ₯Ό κ°μ§ ν¨μλ‘ λ체
MissionUtils.Console.readLineAsync = jest.fn();
// readLineAsync ν¨μμ λμμ ꡬνν¨ - μ
λ ₯κ° λ°°μ΄μμ μμ°¨μ μΌλ‘ κ°μ κ°μ Έμ΄
MissionUtils.Console.readLineAsync.mockImplementation(() => {
const input = inputs.shift();
return Promise.resolve(input);
});
};
λͺ¨μ ν¨μλ₯Ό μ μνκ³ λμλ MissionUtils.Console.readLineAsync ν¨μλ₯Ό κ°μ§ ν¨μλ‘ λ체νλ€. μ¬κΈ°μ μ¬μ©λλ jest.fn( )μ mockImplementation( )μ μ΄λ€ κΈ°λ₯μ ν κΉ?
ꡬνμ΄ jest.fn()μ μ λ¬λλ©΄ μ¬λ°λ₯Έ λͺ¨μ νμ΄νμ΄ μΆλ‘ λ©λλ€. ꡬνμ΄ μλ΅λλ μ¬μ© μ¬λ‘κ° λ§μ΄ μμ΅λλ€. μ ν μμ μ±μ 보μ₯νκΈ° μν΄ μΌλ° μ ν μΈμλ₯Ό μ λ¬ν μ μμ΅λλ€. (μ°Έκ³ : Jest 곡μλ¬Έμ jest.fn)
λͺ¨μ ꡬνμΌλ‘ μ¬μ©ν΄μΌ νλ ν¨μλ₯Ό νμ©ν©λλ€. λͺ¨μ κ°μ²΄ μ체λ λ€μ΄μ€λ λͺ¨λ νΈμΆκ³Ό κ·Έ μ체μμ λμ€λ μΈμ€ν΄μ€λ₯Ό λͺ¨λ κΈ°λ‘ν©λλ€. μ μΌν μ°¨μ΄μ μ λͺ¨μ κ°μ²΄κ° νΈμΆλ λ ꡬνλ μ€νλλ€λ κ²μ λλ€. (μ°Έκ³ : Jest 곡μλ¬Έμ mockImplementation)
βͺοΈ κ³΅μλ¬Έμμμ λ²μ λ§ν¬λ‘ λ€μ μ΄λ ΅κ² μ€λͺ νκ³ μμ§λ§, νμ΄ μ€λͺ νμλ©΄ jest.fn( )μ Jestμμ μ 곡νλ λͺ¨μ ν¨μλ₯Ό μμ±νλ ν¨μλ€. κ·Έλ¦¬κ³ mockImplementation( )λ λͺ¨μ ν¨μμ ꡬνμ μ μνκ³ , κ½€λ 볡μ‘ν λ‘μ§κΉμ§ λ체ν μ μλ€. μ΄λ κ² λλ©΄ readLineAsync ν¨μ λμ , κ°μ§ ν¨μκ° μ¬μ©λμ΄ ν μ€νΈ λμ μ€μ μ¬μ©μ μ λ ₯μ λ°λ λμ κ°μ§ input μΈμλ₯Ό λ°μ μ¬μ©ν μ μκ² λλ€.
MissionUtils.Console.readLineAsync.mockImplementation(() => {
const input = inputs.shift();
return Promise.resolve(input);
βͺοΈ μ΄ λΆλΆλ§ λ°λ‘ λΌμ΄ μμ λ€μ λ³΄κ² λ€. μ°μ readLineAsync ν¨μμ κ°μ§ ꡬνμ μ€μ νλλ° inputs λ°°μ΄μμ shift( )λ₯Ό μ¬μ©ν΄ 첫 λ²μ§Έ μμλ₯Ό μ κ±°νκ³ , μ΄ κ°μ λ°ννλ€. readLineAsyncλ λΉλκΈ° ν¨μμ΄λ―λ‘, λ°νλ κ°μ Promise.resolve(input)λ₯Ό μ¬μ©νμ¬ νλ‘λ―Έμ€λ‘ κ°μΈμ Έ λ°νλλ€.
3οΈβ£ μμΈ‘ κ°λ₯ν κ²°κ³Όλ‘ ν μ€νΈνκΈ°
// λλ€ μ«μλ₯Ό λͺ¨μνλ ν¨μλ₯Ό μ μ
const mockRandoms = (numbers) => {
// MissionUtils.Random.pickNumberInRange ν¨μλ₯Ό κ°μ§ ν¨μλ‘ λ체
MissionUtils.Random.pickNumberInRange = jest.fn();
// pickNumberInRange ν¨μμ λ°νκ°μ μμ°¨μ μΌλ‘ μ μ
numbers.reduce((acc, number) => {
return acc.mockReturnValueOnce(number);
}, MissionUtils.Random.pickNumberInRange);
};
βͺοΈ μ«μ μΌκ΅¬ λ―Έμ μμλ Random.pickNumberInRange (λλ€ μ«μ μμ± ν¨μ)λ₯Ό μ¬μ©νλλ°, ν μ€νΈ μ½λμμλ Jestλ₯Ό μ¬μ©ν΄ μ΄ ν¨μλ₯Ό mock νλ€. mockRandomsλΌλ μ΄λ¦μΌλ‘ μ μΈλ ν¨μλ ν μ€νΈ μ€μ νΉμ λ²μ λ΄μμ λλ€ μ«μλ₯Ό μ ννλ MissionUtils.Random.pickNumberInRange ν¨μμ λμμ λ체νλ€.
μμ MissionUtils.Console.readLineAsync ν¨μλ₯Ό κ°μ§ ν¨μλ‘ λ체ν κ²μ²λΌ, MissionUtils.Random.pickNumberInRange ν¨μ λν Jestμ jest.fn()μ μ¬μ©νμ¬ κ°μ§ ν¨μλ‘ λ체νλ€. μ΄λ κ² νλ©΄ μλμ pickNumberInRange ν¨μ λμ κ°μ§ ν¨μκ° μ¬μ©λμ΄, λλ€ μ«μ μμ±μ λͺ¨μν μ μλ€.
numbers.reduce((acc, number) => {
return acc.mockReturnValueOnce(number);
}, MissionUtils.Random.pickNumberInRange);
βͺοΈ λͺ¨μ ν¨μμ λ¦¬ν΄ κ°μ μ€μ νλ μ λΆλΆλ§ λ°λ‘ λΌμ΄ μμ λ€μ λ³΄κ² λ€. μ¬κΈ°μλ μμ mockRandoms ν¨μκ° μΈμλ‘ λ°μ numbersλΌλ λ°°μ΄μ μ¬μ©νλ€. μ΄ λ°°μ΄μ λͺ¨μν λ λ°νλ λλ€ μ«μλ€μ ν¬ν¨νλ€.
μ°μ numbers λΌλ λ°°μ΄μ μννλ©΄μ reduce ν¨μλ₯Ό μ¬μ©νλ€. μ΄ κ³Όμ μμ MissionUtils.Random.pickNumberInRange ν¨μμ λ°νκ°μ numbers λ°°μ΄μ κ° μμλ‘ μμ°¨μ μΌλ‘ μ€μ νλ€.
κ·Έλ¦¬κ³ mockReturnValueOnce λ©μλλ ν¨μκ° νΈμΆλ λλ§λ€ μ§μ λ μμλλ‘ ν λ²μ© κ°μ λ°ννλλ‘ μ€μ νλ€. μλ₯Ό λ€μ΄, 첫 λ²μ§Έ νΈμΆμμλ numbers λ°°μ΄μ 첫 λ²μ§Έ μμλ₯Ό λ°ννκ³ , λ λ²μ§Έ νΈμΆμμλ λ λ²μ§Έ μμλ₯Ό λ°ννλ μμ΄λ€.
μ 리νμλ©΄, μ ν μ€νΈ μ½λμ λͺ©μ μ λλ€ μ«μ μμ± ν¨μμ λμμ ν΅μ νκ³ , ν μ€νΈ μ€μ μμΈ‘ κ°λ₯νκ³ μΌκ΄λ κ²°κ³Όλ₯Ό μ»κΈ° μν¨μ΄λ€. 'λλ€'μ΄ λ΄ν¬νλ λΆκ·μΉνκ³ , μμΈ‘ λΆκ°λ₯ν μ±μ§μ μ κ±°νκ³ ν μ€νΈ μ½λ μμμ λ§μ λ°©μμΌλ‘ μ μνλ€κ³ 보면 λλ€.
4οΈβ£ μΆλ ₯ ν¨μλ₯Ό κ°μνκΈ°
// λ‘κ·Έ μΆλ ₯μ κ°μνλ ν¨μλ₯Ό μ μ
const getLogSpy = () => {
// MissionUtils.Console.print ν¨μμ νΈμΆμ κ°μ
const logSpy = jest.spyOn(MissionUtils.Console, 'print');
// κ°μ λ‘κ·Έ μ΄κΈ°ν
logSpy.mockClear();
// κ°μ κ°μ²΄ λ°ν
return logSpy;
};
κ·Έ λ€μμλ λ‘κ·Έ μΆλ ₯ ν¨μλ₯Ό κ°μνλ getLogSpy ν¨μλ₯Ό μ μνλ€. μ΄ ν¨μλ λ‘κ·Έ μΆλ ₯μ μν΄ μ¬μ©λλ MissionUtils.Console.print ν¨μμ νΈμΆμ μΆμ νκ³ , κ·Έ κ²°κ³Όλ₯Ό ν μ€νΈμμ μ¬μ©ν μ μκ² νλ€. (spyOnμ λν μ€λͺ μ Jest 곡μ λ¬Έμμ μμ λ₯Ό μ°Έκ³ νλ©΄ μ΄ν΄κ° μ¬μΈ κ²μ΄λ€) μλ¬΄νΌ μ¬κΈ°μλ MissionUtils.Console κ°μ²΄μ print λ©μλκ° νΈμΆλ λλ§λ€ μ΄λ₯Ό μΆμ νλλ‘ μ€μ νλ€.
λλΆμ΄, logSpy.mockClear()λ₯Ό νΈμΆνμ¬ logSpyμ κΈ°λ‘μ μ΄κΈ°νν΄ μ€λ€. μ΄λ ν
μ€νΈ μμ μ μ μ΄μ ν
μ€νΈμμμ νΈμΆ κΈ°λ‘μ μ κ±°νκΈ° μν΄ μ¬μ©λλ©°, κ° ν
μ€νΈ μ μ μλμΌλ‘ λͺ¨μ νλͺ©λ€μ μ§μΈ μ μλ€κ³ νλ€. (μ°Έκ³ : Jest 곡μλ¬Έμ mockClear)
κ·Έ λ€μμλ μ΄κΈ°νλ logSpy κ°μ²΄λ₯Ό λ°ννλ€. μ΄ κ°μ²΄λ₯Ό μ¬μ©νλ©΄ ν μ€νΈ μ½λμμ MissionUtils.Console.print ν¨μμ νΈμΆ μ¬λΆ, νΈμΆ νμ, νΈμΆ μ μ¬μ©λ μΈμ λ±μ κ²μ¬ν μ μμ κ²μ΄λ€.
μ 리νμλ©΄, μ΄ μ½λλ ν μ€νΈ μ€μ μΆλ ₯ ν¨μκ° μ΄λ»κ² μ¬μ©λλμ§ μΆμ νκ³ , λ‘κ·Έ μΆλ ₯μ΄ μμλλ‘ λμνλμ§ κ²μ¦νλ λ° μ¬μ©λλ€. μλ₯Ό λ€μ΄ νΉμ μν©μμ νΉμ λ©μμ§κ° μ μΆλ ₯λλμ§, νΉμ μΆλ ₯ ν¨μκ° μ ν΄μ§ νμλ§νΌ μ νΈμΆλλμ§ λ±μ κ²μ¦ν μ μλ€λ μλ―Έλ€.
5οΈβ£ κ²μ μ’ λ£ ν μ¬μμ λ‘μ§ κ²μ¦νκΈ°
μ½λ λΆμμ μμ, μ°μ ν μ€νΈ μ½λμ ꡬ쑰λ₯Ό μμ보μ. ν μ€νΈ μ½λλ νλμ ν° ν μ€νΈ μ€μνΈ(Test Suite) μμ μ¬λ¬ κ°μ κ΄λ ¨λ ν μ€νΈ μΌμ΄μ€(Test Case)λ€λ‘ μ΄λ£¨μ΄μ Έ μλ€.
ν μ€νΈ μ½λ ꡬ쑰λ κ°λ¨νκ² μμ보μμΌλ, μλμ 첫 λ²μ§Έ ν μ€νΈ μΌμ΄μ€λ₯Ό μͺΌκ°κ°λ©° κΉμνκ² νκ³ λ€μ΄ κ° λ³΄μ.
// 'μ«μ μΌκ΅¬ κ²μ'μ λν ν
μ€νΈ μ€μνΈλ₯Ό μ μ
describe('μ«μ μΌκ΅¬ κ²μ', () => {
// 'κ²μ μ’
λ£ ν μ¬μμ'μ λν ν
μ€νΈ μΌμ΄μ€λ₯Ό μ μ
test('κ²μ μ’
λ£ ν μ¬μμ', async () => {
βͺοΈ μ°μ , describe ν¨μλ₯Ό μ¬μ©νμ¬ 'μ«μ μΌκ΅¬ κ²μ'μ λν ν μ€νΈ μ€μνΈλ₯Ό μ μνλ€. μμμ μ€λͺ νλ― μ΄ λΈλ‘ μμ ν¬ν¨λ test ν¨μλ€μ λͺ¨λ μ΄ 'μ«μ μΌκ΅¬ κ²μ'κ³Ό κ΄λ ¨λ ν μ€νΈμΌ κ²μ΄λ€.
κ·Έλ¦¬κ³ 'κ²μ μ’ λ£ ν μ¬μμ'μ΄λΌλ ν μ€νΈ μΌμ΄μ€λ₯Ό μ μνλ©°, μ΄ ν μ€νΈλ λΉλκΈ°μ μΌλ‘ μ€ν(async)λλ€.
// given
// ν
μ€νΈλ₯Ό μν μ΄κΈ°κ° μ€μ
const randoms = [1, 3, 5, 5, 8, 9];
const answers = ['246', '135', '1', '597', '589', '2'];
const logSpy = getLogSpy();
const messages = ['λ«μ±', '3μ€νΈλΌμ΄ν¬', '1λ³Ό 1μ€νΈλΌμ΄ν¬', '3μ€νΈλΌμ΄ν¬', 'κ²μ μ’
λ£'];
βͺοΈ λ€μμΌλ‘λ ν μ€νΈ μ΄κΈ°κ°μ μ€μ νλ€. μ½λμμ κ·Έλλ‘ μ½νλ― randoms λ°°μ΄μλ κ²μμ μ¬μ©λ λλ€ μ«μλ€μ μ§μ μ μ, answers λ°°μ΄μλ μ¬μ©μμ μ λ ₯μ λͺ¨μνλ λ°μ μ¬μ©λ μμ λ΅λ³λ€μ μ μ, logSpyλ μΆλ ₯μ κ°μνλ ν¨μμ 리ν΄κ°μΌλ‘ μΆλ ₯ ν¨μ νΈμΆμ μΆμ νλ€. κ·Έλ¦¬κ³ messages λ°°μ΄μ μμλλ λ‘κ·Έ λ©μμ§λ€μ ν¬ν¨νλ€.
mockRandoms(randoms);
mockQuestions(answers);
βͺοΈ λͺ¨μ ν¨μλ€μ νΈμΆν΄ νμ±νν΄ μ€λ€. λ mock ν¨μλ₯Ό νΈμΆν λλ μμμ μ μΈν λ°°μ΄μ μΈμλ‘ λ£μ΄μ£Όλ©΄μ κ²μ λ‘μ§μμ μ¬μ©λ λλ€ μ«μμ μ¬μ©μ μ λ ₯μ λͺ¨μνλ€.
// when
// App μΈμ€ν΄μ€ μμ± λ° play ν¨μ μ€ν
const app = new App();
await expect(app.play()).resolves.not.toThrow();
βͺοΈ newλ‘ App ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μμ±νκ³ , play( )λ₯Ό νΈμΆνλ€. κ·Έλ¦¬κ³ μ΄ play( )κ° μμΈλ₯Ό λ°μμν€μ§ μκ³ (not.toThrow) μ μμ μΌλ‘ μνλλμ§ κ²μ¦(expect) νλ€.
// then
// λ‘κ·Έ μΆλ ₯μ΄ μμλλ‘ μ΄λ£¨μ΄μ‘λμ§ κ²μ¦
messages.forEach((output) => {
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining(output));
});
βͺοΈ κ·Έλ¬κ³ λμλ messages λ°°μ΄μ ν¬ν¨λ κ°κ°μ μμ λ©μμ§λ€μ λν΄, μκΉ μΆλ ₯ ν¨μλ₯Ό κ°μνλ€λ logSpyκ° λμ λ€. μ΄ logSpyλ ν΄λΉ λ©μμ§λ₯Ό ν¬ν¨νμ¬ νΈμΆλμλμ§ κ²μ¦νλ μν μ νλ€. μ½κ² λ§ν΄, κ²μμ΄ μ§νλλ©° κ° μν©μ λ§λ λ‘κ·Έ λ©μμ§λ₯Ό μΆλ ₯νκ³ μλμ§ μλμ§ νμΈνλ κ²μ΄λ€.
μ°Έκ³ λ‘, μ¬κΈ°μ toHaveBeenCalledWith( )λ λͺ¨μ ν¨μκ° νΉμ μΈμλ‘ νΈμΆλμλμ§ νμΈνλ μν μ νλ©°, expect.stringContainingλ μν©μ λ§κ² μ νν μμ λ¬Έμμ΄μ ν¬ν¨νλ λ¬Έμμ΄μΈ κ²½μ°λ₯Ό νμΈνλ μν μ νλ€.
6οΈβ£ μμΈ μν© μ²λ¦¬ μ¬λΆ ν μ€νΈνκΈ°
// 'μμΈ ν
μ€νΈ'μ λν ν
μ€νΈ μΌμ΄μ€λ₯Ό μ μ
test('μμΈ ν
μ€νΈ', async () => {
βͺοΈ μ°μ , 'μμΈ ν μ€νΈ'λΌλ μ΄λ¦μ ν μ€νΈ μΌμ΄μ€λ₯Ό μ μνλ©° μ΄ ν μ€νΈ λν λΉλκΈ° ν¨μλ₯Ό ν μ€νΈνκΈ° μν΄ asyncλ₯Ό μ¬μ©νλ€.
// given
// ν
μ€νΈλ₯Ό μν μ΄κΈ°κ° μ€μ
const randoms = [1, 3, 5];
const answers = ['1234'];
βͺοΈ μ²« λ²μ§Έ ν μ€νΈ μΌμ΄μ€μ μ μ¬νκ² ν μ€νΈ μ΄κΈ°κ°μ μ€μ νλ€. randoms λ°°μ΄μ ν μ€νΈμ μ¬μ©λ λλ€ μ«μλ€, answers λ°°μ΄μ ν μ€νΈμ μ¬μ©λ μ¬μ©μ μ λ ₯μ λͺ¨μνμ¬ μμ λ΅λ³μ μ μνλ€.
μ°Έκ³ λ‘ μ΄ ν μ€νΈλ μμΈλ₯Ό λ°μμν€λμ§ μμ보λ ν μ€νΈμ΄κΈ° λλ¬Έμ μλ¬λ₯Ό λ°μμμΌμΌ νλ€. λλ¬Έμ answersμλ μμΈ μ²λ¦¬ λμμΈ λ΅λ³(μΈ μλ¦¬κ° μλ λ€ μ리 λ¬Έμμ΄)μ λ£μ΄μΌ νλ€.
mockRandoms(randoms);
mockQuestions(answers);
βͺοΈ λ§μ°¬κ°μ§λ‘ μμμ μ μΈν λ°°μ΄λ€μ μΈμλ‘ λ£μ΄ mock ν¨μλ₯Ό νΈμΆνλ€.
// when & then
// App μΈμ€ν΄μ€ μμ± λ° play ν¨μ μ€ν, μμΈ λ°μ κ²μ¦
const app = new App();
await expect(app.play()).rejects.toThrow('[ERROR]');
βͺοΈ newλ‘ App ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μμ±νκ³ , play( )λ₯Ό νΈμΆνλ€. κ·Έλ¦¬κ³ μ΄ play( )κ° μμΈλ₯Ό λ°μμν€κ³ (toThrow), μμΈ λ©μμ§λ‘ '[ERROR]'κ° μΆλ ₯λλμ§ νμΈνλ€.
π©π»π» ν μ€νΈ μ½λ λΆμ μκ°
νμ€ν μ λ³΄λ€ ν μ€νΈ μ½λκ° μ μ΄ν΄λλ€. μ²μ λ΄€μ λλ λΉμ°νκ²λ Jestμ κ° λ©μλκ° μ΄λ€ μν μ νλμ§ λͺ¨λ₯΄κΈ°μ κΉλ§λμ΄ λ κΈ°λΆμ΄μμ§λ§, νλνλ μ°Ύμλ³΄κ³ λΆμν΄λ³΄λ μ μ½νλ€. λ§μΉ μμ΄λ₯Ό νλλ λͺ¨λ₯΄λλ° μμ΄μ¬μ μμ λ¨μ΄ νλνλ μ°Ύμκ°λ©΄μ λ¬Έλ¨μ μ½μ΄λΈ λλ?
μ΄μ¨λ ν μ€νΈ μ½λλ₯Ό μΈμΈνκ² ν보λ λ¬Έμ μμ μꡬνλ λ°λ₯Ό μ ννκ² μ μ μμλ€. λ€μ λ―Έμ λ€λ μ΄λ κ² νλ΄μΌμ§.
λκΈ