Jest Mock Functions

슬로그·2024년 4월 9일
0

Jest

목록 보기
2/2
post-thumbnail

1. stub와 mock은 상태검증이냐 행위검증이냐에 따라 구분될 수 있다.

상태검증이란?

메서드가 수행될때 연관되어있는 협력 객체의 ‘상태’를 검증함으로써 제대로 기능이 동작하고 있는지를 검증하는것

행위검증 이란?

테스트하고자 하는 메소드가 참조하고있는 협력 객체의 메소드를 제대로 콜 하는지에 대한 ‘행위’를 검증하는 것

stub와 mock

stub(상태 검증)

  • 더미 객체를 생성하고 실제로 동작하는 것처럼 보이게 만든 가짜 객체
  • 호출된 요청에 대한 응답값을 미리 만들어놓고 전달한다.
  • 객체의 최소한의 기능만을 임의로 구현한다.

mock(행위 검증)

  • 특정동작을 수행하는지(메소드를 제대로 콜 하는지)에 대한 검증

Mock Functions

사용해보기 ✍️

예를 들어 한 js 코드가 있다.

//forEach.js

export function forEach(items, callback) {
  for (const item of items) {
    callback(item);
  }
}

이 함수를 test하기 위해서 jest에서는 mock function 이라는 것을 통해 mock 함수의 상태를 검사하여 콜백이 제대로 호출되는지 검사할 수 있다.

//forEach.test.js

const forEach = require('./forEach');

const mockCallback = jest.fn(x => 42 + x);

test('forEach mock function', () => {
	// 1.
  forEach([0, 1], mockCallback);

  // 2.
  expect(mockCallback.mock.calls).toHaveLength(2);

  // 3.
  expect(mockCallback.mock.calls[0][0]).toBe(0);

  // The first argument of the second call to the function was 1
  expect(mockCallback.mock.calls[1][0]).toBe(1);

  // The return value of the first call to the function was 42
  expect(mockCallback.mock.results[0].value).toBe(42);
});
  1. 먼저 forEach함수에 배열[0,1] 과 mockCallback을 전달하는데 , mockCallback은 인자를 42+ 해주는 함수이다.

  2. 그럼 이 함수를 test하기 위해서 expect로 test 해줄수 있다. 이때 .mock.calls를 같이 써주고 그다음 원하는 api를 적용해주면 된다.

  3. mockCallback.mock.calls[0][0] 의 의미는 0번째로 호출된 , 0번째(첫번째) 인자를 뜻하고 0을 의미한다.

  4. mockCallback.mock.calls[1][0] 는 그럼 1번째로 호출된 , 0번째 인자를 뜻하고 1을 나타내준다.

  5. mockCallback.mock.results 각 호출에 대한 정보는 객체로써 typevalue 속성을 가진다.

    expect(mockCallback.mock.results[0].value).toBe(42);는 첫 번째 호출이 정상적으로 반환된 경우에 해당한다.expect(mockCallback.mock.results[0].value).toBe("error");는 첫 번째 호출이 예외를 던져서 반환된 경우를 기대하는 것이므로, type이 'throw'이고 value가 에러 값을 가리키게 된다.

test code에서 Mock 함수에 value값 전달하기

const myMock = jest.fn();
console.log(myMock());
// > undefined

myMock.mockReturnValueOnce(10).mockReturnValueOnce('x').mockReturnValue(true);

console.log(myMock(), myMock(), myMock(), myMock());
// > 10, 'x', true, true

test code를 작성하면서 mockReturnValueOnce을 통해 value값을 넣어줄수도있다.

Mocking Modules

만약 axios를 사용해 API를 받아오는 경우에도 Mocking을 통해 실제로 호출하지 않고 axios 모듈을 자동으로 모의 테스트 할 수 있다.

//users.test.js

import axios from 'axios';
import Users from './users';

jest.mock('axios');

test('should fetch users', () => {
  const users = [{name: 'Bob'}];
  const resp = {data: users};
  axios.get.mockResolvedValue(resp);

  // or you could use the following depending on your use case:
  // axios.get.mockImplementation(() => Promise.resolve(resp))

  return Users.all().then(data => expect(data).toEqual(users));
});

moxkResolvedValue API를 통해 가짜로 axios를 get 할 수 있다. !

Mock Implementations

가상으로 mock 함수를 만들고 jest.fn으로 연결해 줄 수 있다.

먼저 가상으로 mock 함수를 파일을 import 해오고 연결하려면

const testDataFatch = require("../testDataFatch")

jest.mock('../testDataFatch');

이렇게 연결시켜 준다. 이렇게 확인해보니 mock 함수가 딱 이해가 갔다..!

testDataFatch의 가상의 데이터를 만들어주려면 jest.fn을 통해 만들어주면 된다.

const items = jest.fn(aync() =>{
	[
		item:1 , data:"가상",
		item:2, data:"데이터"
	]
})

만들어준 items와 mock을 연결시켜줘야하는데 이때 사용하는 것이 mockImplementation 이다.

fetchData.mockImplementation(()=>{
	return{
		items
		//items: items
	}
})

mock함수와 mockImplementation을 통해서 어떤 함수를 호출했을때 어떤 데이터를 받아올수 있는지 쉽게 컨트롤 할수 있다.

테스트 코드는 이렇게 컨트롤 함으로써 데이터 받아오는걸 실패하던 성공하던 환경적인 요인에 영향을 받지않고 원하는 로직만 검증(행위검증 또는 상태검증)할 수 있는것이다.

이렇게 구성하는것을 단위 테스트라고 한다.


참고 📒

https://jestjs.io/docs/mock-function-api

profile
빨리가는 유일한 방법은 제대로 가는것

0개의 댓글

관련 채용 정보