μΉ΄ν…Œκ³ λ¦¬ μ—†μŒ

λ‹¨μœ„ν…ŒμŠ€νŠΈ: jestλ₯Ό μ΄μš©ν•œ λ‹¨μœ„ν…ŒμŠ€νŠΈ

stonesy 2023. 11. 27. 00:08
728x90

πŸ”λ‹¨μœ„ ν…ŒμŠ€νŠΈ(Unit Test)

λ‹¨μœ„ ν…ŒμŠ€νŠΈλž€ ν”„λ‘œκ·Έλž˜λ° ν›„ ν”„λ‘œκ·Έλž¨μ˜ κΈ°λ³Έ λ‹¨μœ„μΈ λͺ¨λ“ˆμ΄ μ˜λ„λŒ€λ‘œ μ •ν™•νžˆ μž‘λ™ν•˜λŠ”μ§€ κ²€μ¦ν•˜λŠ” μ ˆμ°¨μ΄λ‹€. 즉, μ†ŒμŠ€ μ½”λ“œμ˜ κ°œλ³„ λ‹¨μœ„λ₯Ό ν…ŒμŠ€νŠΈν•˜μ—¬ μ‚¬μš©ν•  μ€€λΉ„κ°€ λ˜μ—ˆλŠ”μ§€ ν™•μΈν•˜λŠ” ν…ŒμŠ€νŠΈ 방법이닀.

 

βœ”οΈλ‹¨μœ„ ν…ŒμŠ€νŠΈλ₯Ό ν•˜λŠ” 이유

  1. μ‹€μ œ ν™˜κ²½μ—μ„œ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κΈ° μ–΄λ €μš΄ 경우 μœ λ‹› ν…ŒμŠ€νŠΈλ₯Ό 톡해 μ½”λ“œκ°€ μ •μƒμ μœΌλ‘œ λ™μž‘ν•˜λŠ”μ§€ 확인할 수 μžˆλ‹€.
  2. 쒅속성이 μžˆλŠ” λ‹€λ₯Έ ν΄λž˜μŠ€λ“€μ—μ„œ 버그가 λ°œμƒν•˜λŠ” 것을 λ°©μ§€ν•˜κΈ° μœ„ν•΄μ„œμ΄λ‹€.

 

βœ”οΈλ‹¨μœ„ ν…ŒμŠ€νŠΈμ˜ 쑰건

  1. ν…ŒμŠ€νŠΈ μ½”λ“œλŠ” λΉ λ₯΄κ²Œ λ™μž‘ν•˜λ©° 자주 돌릴 수 μžˆμ–΄μ•Ό ν•œλ‹€.
  2. 각각의 ν…ŒμŠ€νŠΈλŠ” 독립적이어야 ν•˜λ©° μ„œλ‘œ μ˜μ‘΄ν•΄μ„œλŠ” μ•ˆλœλ‹€.
  3. μ–΄λŠ ν™˜κ²½μ—μ„œλ„ 반볡 κ°€λŠ₯ν•΄μ•Ό ν•œλ‹€.
  4. ν…ŒμŠ€νŠΈλŠ” 성곡 λ˜λŠ” μ‹€νŒ¨λ‘œ bool κ°’μœΌλ‘œ κ²°κ³Όλ₯Ό λ‚΄μ–΄ 자체적으둜 κ²€μ¦λ˜μ–΄μ•Ό ν•œλ‹€.
  5. ν…ŒμŠ€νŠΈλŠ” μ μ‹œμ— 즉, ν…ŒμŠ€νŠΈν•˜λ €λŠ” μ‹€μ œ μ½”λ“œλ₯Ό κ΅¬ν˜„ν•˜κΈ° 직전에 κ΅¬ν˜„ν•΄μ•Ό ν•œλ‹€.

 

πŸ”Javascriptμ—μ„œ λ‹¨μœ„ν…ŒμŠ€νŠΈν•˜κΈ°: Jest

JestλŠ” νŽ˜μ΄μŠ€λΆμ—μ„œ λ§Œλ“€μ–΄μ„œ React와 λ”λΆˆμ–΄ λ§Žμ€ μžλ°”μŠ€ν¬λ¦½νŠΈ κ°œλ°œμžλ“€λ‘œλΆ€ν„° μ‚¬λž‘λ°›κ³  μžˆλŠ” ν…ŒμŠ€νŒ… λΌμ΄λΈŒλŸ¬λ¦¬μ΄λ‹€. 이번 μš°ν…Œμ½” ν”„λ¦¬μ½”μŠ€μ— μ°Έμ—¬ν•˜λ©΄μ„œ 처음 μ‚¬μš©ν•΄λ³΄μ•˜λ‹€.

 

βœ”οΈμ„€μΉ˜

λ‹€μŒ λͺ…λ Ήμ–΄λ₯Ό 톡해 jestλ₯Ό μ„€μΉ˜ν•œλ‹€.

npm install jest —save-dev

package.json에 λ‹€μŒκ³Ό 같이 μΆ”κ°€(μˆ˜μ •)ν•œλ‹€. 이 과정을 톡해 터미널에 npm testλ₯Ό μž…λ ₯ν•˜λ©΄ jest μ»€λ§¨λ“œλ₯Ό μ‹€ν–‰ν•  수 있게 λœλ‹€.

scripts:{”test”: “jest —watch”}

 

βœ”οΈJest 기본문법

// ν…ŒμŠ€νŠΈν•  μ½”λ“œ
export const add = (x, y) => x + y;

// ν…ŒμŠ€νŒ… μ½”λ“œ
describe("add", () => {
  test("should add two numbers", () => {
    expect(add(1, 1)).toBe(2);
		expect(add(1, -4)).toBe(-3);
  }
);
  • describeλŠ” μ—¬λŸ¬ ν…ŒμŠ€νŒ… μ½”λ“œλ₯Ό ν•˜λ‚˜λ‘œ 묢을 λ•Œ μ‚¬μš©ν•œλ‹€.
  • testλŠ” μ‹€μ œλ‘œ ν…ŒμŠ€νŒ…μ„ μ‹€ν–‰ν•˜λŠ” μ½”λ“œμ΄λ‹€.
  • expectλŠ” 값을 ν…ŒμŠ€νŠΈν•  λ•Œλ§ˆλ‹€ matcher와 ν•¨κ»˜ μ‚¬μš©ν•œλ‹€.
  • matcherλŠ” λ‚΄κ°€ μ›ν•˜λŠ” λ°©λ²•μœΌλ‘œ 값을 ν…ŒμŠ€νŠΈν•˜λ„λ‘ ν•  수 μžˆλ‹€.
    • toBe() : ν•΄λ‹Ή κ°’κ³Ό μΌμΉ˜ν•˜λ©΄ 톡과
    • toBeNull() toBeUndefined() toBeDefined() : 인 경우 톡과
    • toBeTruthy() toBeFasly() : boolean κ°’ νŒλ³„
    • toBeGreaterThan λ“±… : 이상, μ΄ν•˜, 초과, 미만
    • toMatch(/H/) : μ •κ·œ ν‘œν˜„μ‹μœΌλ‘œ λ¬Έμžμ—΄ νŒλ‹¨

 

 

πŸ”κ°€μ§œκ°μ²΄(Mock Object)

μ΄λ•Œ, 각각의 ν…ŒμŠ€νŠΈμ½”λ“œλŠ” 독립적이어야 ν•˜λ©° μ„œλ‘œ μ˜μ‘΄ν•΄μ„œλŠ” μ•ˆλœλ‹€κ³  ν–ˆλ‹€. λ”°λΌμ„œ λ‹€λ₯Έ 객체와 μ£Όκ³  λ°›λŠ” κ²½μš°μ— λ¬Έμ œκ°€ λ°œμƒν•œλ‹€. 이 경우 λ‹€λ₯Έ 객체 λŒ€μ‹ μ— κ°€μ§œ 객체(Mock Object)λ₯Ό μ£Όμž…ν•΄ νŠΉμ • κ²°κ³Όλ₯Ό λ°˜ν™˜ν•˜λΌκ³  정해진 닡변을 μ€€λΉ„μ‹œμΌœμ•Ό ν•œλ‹€.

⇒λŒ€ν‘œμ μΈ μ˜ˆμ‹œλ‘œλŠ” μž…μΆœλ ₯ν…ŒμŠ€νŠΈκ°€ μžˆλ‹€.

describe("μ£Όλ¬Έ μž…λ ₯ ν…ŒμŠ€νŠΈ",()=>{
	test("주문이 ν˜•μ‹μ— λ§žμ§€ μ•ŠμœΌλ©΄ μ˜ˆμ™Έκ°€ λ°œμƒν•œλ‹€.",()=>{
		const mockReadLineAsync = jest.fn().mockResolvedValue("ν•΄μ‚°λ¬ΌνŒŒμŠ€νƒ€,μ΄ˆμ½”μΌ€μ΄ν¬-3");
        jest.spyOn(Console, "readLineAsync").mockImplementation(mockReadLineAsync);
		expect(()=>InputView.getOrder()).rejects.toThrow(inputViewErrorMessage.ERROR_INPUT_ORDER_REGEX);
	});
});
import { EOL as LINE_SEPARATOR } from 'os';

describe("OutputView ν…ŒμŠ€νŠΈ",()=>{
	test("μ£Όλ¬Έ 메뉴λ₯Ό 좜λ ₯ν•œλ‹€.",()=>{
		const spy = jest.spyOn(Console, "print");
        const outputMessage = [`${}`+LINE_SEPARATOR+`${}`+LINE_SEPARATOR+`${}`];
        
        outputView.printOrder();
        
        outputMessage.forEach((log)=>{
        	expect([...spy.mock.calls).join(LINE_SEPARATOR)).toContain(log);
        });
	});
});
728x90