Bruno의 jest 강의 3 (mocking)

YEONGHUN KO·2022년 8월 13일
0

JAVASCRIPT TESTING

목록 보기
5/11
post-thumbnail

Mocking React Components and Functions using Jest

spyOn

obj.method에서 method가 몇 번 호출되었는지, 무슨 para가 pass되었는지를 tracking할 수 있다. 그리고 method가 어떤 값을 리턴하는지 정할 수 도 있다. 첫번째 arg에는 obj를 두번째는 method를 pass하면 된다.

// randomNum.js
export function randomBetween(min: number, max: number) {
  // Thanks GitHub Co-Pilot!
  // min and max included
  return Math.floor(Math.random() * (max - min + 1) + min);
}

// randomNum.spec.js
import { randomNum } from './randomNum';
const randomSpy = jest.spyOn(Math, 'random');

describe('randomNum', () => {
  describe('when Math.random is 0', () => {
    beforeEach(() => {
      // tell spy to forget about the past and look into the future
      randomSpy.mockClear().mockReturnValue(0);
    });

    it('called with max=5,min=3 and returns 3', () => {
      expect(randomNum(3, 5)).toBe(3);
      expect(randomSpy).toHaveBeenCalledTimes(1);
    });
  });
});

mockImplementation을 이용하면 mocking하는 method에 pass되는 arg에 따라서 임의의 값을 리턴할 수 도 있다.

randomSpy.mockImplementation(para => {
  if (para) {
    return 5;
  }
});

jest.fn

함수를 마킹할때는 jest.fn을 써야 mockReturnValue 을 test안에서 사용가능하다

import { useRouter } from 'next/router'
import List from '../List'

jest.mock('next/router', () => ({
  useRouter: jest.fn()
}))

describe('components/List', () => {

  test('It renders with an empty query', () => {
    
    const pushMock = jest.fn()
    useRouter.mockReturnValue({ query: {},push: pushMock})
    ...
    
}

useRouter가 jest mocking 함수로 치환해야 mockReturnValue 라는 함수를 사용할 수 있게 되고 그 안에서 useRouter의 api를 내가 mocking가능할 수 있게 된다.

done

test에 두번째로 들어가는 callback에는 인자를 받아올 수 있다. 주로 done이라고 이름짓는다. done이 호출되어야만 테스트가 끝난다. 만약 done이 호출되지 않으면 timeout error가 나타난다.

test('the data is peanut butter', done => {
  function callback(error, data) {
    if (error) {
      done(error);
      return;
    }
    try {
      expect(data).toBe('peanut butter');
      done();
    } catch (error) {
      done(error);
    }
  }

  fetchData(callback);
});

test subset of recieved object

test('onPress gets called with the right thing', () => {
  const onPress = jest.fn();
  simulatePresses(onPress);
  expect(onPress).toBeCalledWith(
    expect.objectContaining({
      x: expect.any(Number),
      y: expect.any(Number),
    })
  );
});

__mocks__

underscore이 두개있고 대소문자 신경쓰자! 이렇게 폴더를 만들고 안에 simpleVersion컴포넌트를 만들면 jest.mock할때 자동으로 __mocks__ 안에 있는 simpleVersion을 mocking하게 되니 참고하자!

그리고 mock할려고 하는 파일이름이랑 똑같은 이름이어야 한다!

바로 코드로 가보자.

pages/Main.js를 mocking하려고 한다고 해보자. 그럼 아래와 같이 폴더와 파일을 만들면 된다.

pages
├─ __mocks__
│  └─ Main.js
├─ CourseDetail.js
├─ Loader.js
└─ Main.js
//pages/__mocks__/Main.js
export default function Main() {
  return <div>Mocked Main</div>;
}

// __test__/Main.spec.js

import { render, screen } from '@testing-library/react';

import Main from '../../pages/Main';

jest.mock('../../pages/Main');

it.only('test mocked header', () => {
  render(<Main />);
  screen.debug();
});

// console.log
//   <body>
//     <div>
//       <div>
//         Mocked Main
//       </div>
//     </div>
//   </body>

Main을 mocking했다.

https://jestjs.io/docs/manual-mocks#mocking-user-modules 참고!

profile
'과연 이게 최선일까?' 끊임없이 생각하기

0개의 댓글