๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
JavaScript/js ๋ฌธ๋ฒ•

jest.spyOn

by GREEN๋‚˜๋ฌด 2025. 3. 24.
728x90

๐Ÿ”ต ๊ฐœ๋… ๋ฐ ์—ญํ• 

  • ์ŠคํŒŒ์ด(Spy): ์‹ค์ œ ํ•จ์ˆ˜์˜ ๋™์ž‘์€ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋ฉด์„œ, ํ˜ธ์ถœ ์—ฌ๋ถ€, ํ˜ธ์ถœ ํšŸ์ˆ˜, ์ „๋‹ฌ๋œ ์ธ์ž ๋“ฑ์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.
  • ๋ชฉ์ : ํ•จ์ˆ˜์˜ ๋‚ด๋ถ€ ๋กœ์ง์€ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๊ณ , ํ•จ์ˆ˜๊ฐ€ ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉ๋˜์—ˆ๋Š”์ง€๋ฅผ ๊ฐ์‹œํ•˜์—ฌ ํ…Œ์ŠคํŠธ์˜ ์‹ ๋ขฐ์„ฑ์„ ๋†’์ด๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

๐Ÿ”ต ๊ธฐ๋ณธ ์‚ฌ์šฉ๋ฒ•

  1. ์ŠคํŒŒ์ด ์ƒ์„ฑํ•˜๊ธฐ
    const calculator = {
      add: (a, b) => a + b,
    };
    
    // 'calculator' ๊ฐ์ฒด์˜ 'add' ๋ฉ”์„œ๋“œ์— ์ŠคํŒŒ์ด ๋ถ€์ฐฉ
    const spyFn = jest.spyOn(calculator, 'add');
    
  2. ํ•จ์ˆ˜ ํ˜ธ์ถœ ๋ฐ ๊ฒฐ๊ณผ ๊ฒ€์ฆ
    const result = calculator.add(2, 3);
    
    // ํ˜ธ์ถœ ํšŸ์ˆ˜ ํ™•์ธ
    expect(spyFn).toHaveBeenCalledTimes(1);
    // ์ „๋‹ฌ๋œ ์ธ์ž ํ™•์ธ
    expect(spyFn).toHaveBeenCalledWith(2, 3);
    // ํ•จ์ˆ˜์˜ ์‹ค์ œ ๊ฒฐ๊ณผ๊ฐ’ ํ™•์ธ
    expect(result).toBe(5);
    
    • ์„ค๋ช…: ์œ„ ์˜ˆ์ œ๋Š” jest.spyOn()์„ ์‚ฌ์šฉํ•˜์—ฌ add ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋œ ํšŸ์ˆ˜์™€ ์ธ์ž๋ฅผ ๊ฒ€์ฆํ•˜๋ฉด์„œ๋„, ํ•จ์ˆ˜์˜ ์›๋ž˜ ๋™์ž‘(๋‘ ์ˆ˜์˜ ํ•ฉ)์„ ๊ทธ๋Œ€๋กœ ์ˆ˜ํ–‰ํ•จ์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.

๐Ÿ”ต ํ™•์žฅ ๊ธฐ๋Šฅ ๋ฐ ํ™œ์šฉ๋ฒ•

  1. ํ•จ์ˆ˜ ๋™์ž‘ ๋Œ€์ฒด (mockImplementation)
    • ๋ชฉ์ : ํ…Œ์ŠคํŠธ ์ƒํ™ฉ์— ๋”ฐ๋ผ ํ•จ์ˆ˜์˜ ๋™์ž‘์„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    • ์˜ˆ์ œ:
      jest.spyOn(myObject, 'myMethod').mockImplementation(arg => `Mocked, ${arg}!`);
      console.log(myObject.myMethod('World')); // ์ถœ๋ ฅ: "Mocked, World!"
      
    • ์„ค๋ช…: ์œ„ ์˜ˆ์ œ๋Š” myMethod์˜ ์›๋ž˜ ๋กœ์ง ๋Œ€์‹  ์ง€์ •ํ•œ ๋กœ์ง์œผ๋กœ ๋™์ž‘ํ•˜๋„๋ก ์„ค์ •ํ•˜์—ฌ, ํŠน์ • ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค์— ๋งž๋Š” ๊ฒฐ๊ณผ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  2. ์›๋ณธ ํ•จ์ˆ˜ ๋ณต๊ตฌ (mockRestore)
    • ๋ชฉ์ : ํ…Œ์ŠคํŠธ ํ›„ ์›๋ž˜ ํ•จ์ˆ˜์˜ ์ƒํƒœ๋กœ ๋ณต๊ตฌํ•˜์—ฌ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.
    • ์˜ˆ์ œ:
      const spy = jest.spyOn(myObject, 'myMethod');
      // ... ํ…Œ์ŠคํŠธ ์ฝ”๋“œ ์‹คํ–‰ ...
      spy.mockRestore();  // ์›๋ณธ ํ•จ์ˆ˜๋กœ ๋ณต๊ตฌ
      
    • ์„ค๋ช…: ๋ณต๊ตฌํ•˜์ง€ ์•Š์œผ๋ฉด ์ŠคํŒŒ์ด๊ฐ€ ๋‚จ์•„ ๋‹ค๋ฅธ ํ…Œ์ŠคํŠธ์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ํ…Œ์ŠคํŠธ ํ›„ ๋ฐ˜๋“œ์‹œ ์›๋ž˜ ์ƒํƒœ๋กœ ๋Œ๋ ค๋†“์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ”ต ์‹ค์ œ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ์˜ ์‚ฌ์šฉ ์˜ˆ์‹œ

  1. ์™ธ๋ถ€ API ํ…Œ์ŠคํŠธ
    • ์˜ˆ๋ฅผ ๋“ค์–ด, axios ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ, ๋‚ด๋ถ€ axios.get ํ•จ์ˆ˜์— ์ŠคํŒŒ์ด๋ฅผ ๋ถ€์ฐฉํ•˜์—ฌ API ํ˜ธ์ถœ์„ ๊ฐ์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    const axios = require("axios");
    const userService = require("./userService");
    
    test("findOne fetches data from the API endpoint", async () => {
      const spyGet = jest.spyOn(axios, "get");
      await userService.findOne(1);
      expect(spyGet).toHaveBeenCalledTimes(1);
      expect(spyGet).toHaveBeenCalledWith(`https://jsonplaceholder.typicode.com/users/1`);
    });
    
    • ์ฃผ์˜์‚ฌํ•ญ: ์™ธ๋ถ€ API์— ์˜์กดํ•˜์ง€ ์•Š๋„๋ก, ํ•„์š”ํ•œ ๊ฒฝ์šฐ jest.fn()์„ ํ™œ์šฉํ•ด ๊ฐ€์งœ ํ•จ์ˆ˜๋กœ ๋Œ€์ฒดํ•˜์—ฌ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์„ ๋…๋ฆฝ์ ์œผ๋กœ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. ํ…Œ์ŠคํŠธ์˜ ๊ฒฐ์ •์„ฑ(Deterministic) ํ™•๋ณด
    • ๋ชฉ์ : ๋„คํŠธ์›Œํฌ ์ƒํƒœ๋‚˜ API ์„œ๋ฒ„์˜ ์‘๋‹ต์— ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š๊ณ  ํ•ญ์ƒ ๋™์ผํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋‚ด๋„๋ก ํ…Œ์ŠคํŠธ๋ฅผ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.
    • ๋ฐฉ๋ฒ•: axios.get๋ฅผ jest.fn().mockResolvedValue()๋กœ ๋Œ€์ฒดํ•˜์—ฌ ๊ณ ์ •๋œ ๊ฒฐ๊ณผ๋ฅผ ๋ฆฌํ„ดํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
    axios.get = jest.fn().mockResolvedValue({
      data: {
        id: 1,
        name: "Dale Seo",
      },
    });
    

๐Ÿ”ต ์š”์•ฝ

  • jest.spyOn()์€ ํ•จ์ˆ˜์˜ ํ˜ธ์ถœ ์ •๋ณด๋ฅผ ๊ฐ์‹œํ•˜๋ฉด์„œ๋„ ์›๋ณธ ๋กœ์ง์„ ๊ทธ๋Œ€๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฐ•๋ ฅํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.
  • ํ•„์š”์— ๋”ฐ๋ผ ํ•จ์ˆ˜์˜ ๋™์ž‘์„ ๋ณ€๊ฒฝํ•˜๊ฑฐ๋‚˜, ํ…Œ์ŠคํŠธ ํ›„ ์›๋ž˜ ์ƒํƒœ๋กœ ๋ณต๊ตฌํ•˜๋Š” ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ํ™œ์šฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด๋ฅผ ํ†ตํ•ด ํ…Œ์ŠคํŠธ์˜ ์‹ ๋ขฐ์„ฑ์„ ๋†’์ด๊ณ , ์™ธ๋ถ€ ํ™˜๊ฒฝ์— ์˜์กดํ•˜์ง€ ์•Š๋Š” ์•ˆ์ •์ ์ธ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์„ ๊ตฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์ถœ์ฒ˜

https://inpa.tistory.com/entry/JEST-%F0%9F%93%9A-%EB%AA%A8%ED%82%B9-mocking-jestfn-jestspyOn#mocking_%EB%A9%94%EC%86%8C%EB%93%9C_-_jest.spyon

 

https://www.daleseo.com/jest-fn-spy-on/