Jest
는 페이스북에서 만들어서 React와 더불어 많은 자바스크립트 개발자들로 부터 좋은 반응을 얻고 있는 테스팅 라이브러리다.
toBe
는 참조값(주소값)을 비교하는 함수이다.
toEqual
은 값? 을 비교하는 함수이다.
toBe
는 다르다고 나온다.toEqual
은 실제 값을 비교하기 때문에 객체 내부의 값이 동일하다면 같다고 나온다.toStrictEqual
: undefined
를 허용하지 않는다.number
, boolean
, string
에는 참조값이 정해져 있어서 차이가 없다.describe('to be vs to equal', () => {
test('test', () => {
const a = [1];
expect(a).toBe([1]); // false
});
test('test', () => {
const a = [1];
expect(a).toEqual([1]); // true
});
test('test', () => {
expect([1]).toBe([1]); // false
});
});
getJasmineRequireObj().toBe = function(j$) {
/**
* {@link expect} the actual value to be `===` to the expected value.
* @function
* @name matchers#toBe
* @since 1.3.0
* @param {Object} expected - The expected value to compare against.
* @example
* expect(thing).toBe(realThing);
*/
function toBe(matchersUtil) {
var tip = ' Tip: To check for deep equality, use .toEqual() instead of .toBe().';
return {
compare: function(actual, expected) {
var result = {
pass: actual === expected
};
if (typeof expected === 'object') {
result.message = matchersUtil.buildFailureMessage('toBe', result.pass, actual, expected) + tip;
}
return result;
}
};
}
return toBe;
};
getJasmineRequireObj().toEqual = function(j$) {
/**
* {@link expect} the actual value to be equal to the expected, using deep equality comparison.
* @function
* @name matchers#toEqual
* @since 1.3.0
* @param {Object} expected - Expected value
* @example
* expect(bigObject).toEqual({"foo": ['bar', 'baz']});
*/
function toEqual(matchersUtil) {
return {
compare: function(actual, expected) {
var result = {
pass: false
},
diffBuilder = j$.DiffBuilder({prettyPrinter: matchersUtil.pp});
result.pass = matchersUtil.equals(actual, expected, diffBuilder);
// TODO: only set error message if test fails
result.message = diffBuilder.getMessage();
return result;
}
};
}
return toEqual;
};
1. Promise 객체로 받는 경우
test('the data is peanut butter', () => {
return fetchData().then(data => {
expect(data).toBe('peanut butter');
});
});
→ return을 해야하는 이유: return을 사용해야 jest는 promise
가 resolve
될 때까지 기다리기 때문이다.
.resolves/.rejects 사용하면
test('the data is peanut butter', () => {
return expect(fetchData()).resolves.toBe('peanut butter');
});
test('the fetch fails with an error', () => {
return expect(fetchData()).rejects.toMatch('error');
});
반드시 return을 해야한다.
→ return이 없으면 data를 fetch 하고 콜백을 실행하기 전에 테스트가 완료됨
2. async/await
test('the data is peanut butter', async () => {
const data = await fetchData();
expect(data).toBe('peanut butter');
});
test('the fetch fails with an error', async () => {
expect.assertions(1);
try {
await fetchData();
} catch (error) {
expect(error).toMatch('error');
}
});
test('the data is peanut butter', async () => {
await expect(fetchData()).resolves.toBe('peanut butter');
});
test('the fetch fails with an error', async () => {
await expect(fetchData()).rejects.toMatch('error');
});
올바른 promise는 reloves
로 풀고 toBe
로 비교한다.
에러 promise는 rejects
로 받고 toMatch
로 비교한다.
→ toMatch는 정규식 비교
→ toBe로 비교하면 안되나?
→ toThrow 쓸듯
toThrow 예시 코드
test("Test description", () => {
const t = () => {
throw new TypeError("UNKNOWN ERROR");
};
// 타입에러 객체 확인
expect(t).toThrow(TypeError);
// 에러 메시지 확인
expect(t).toThrow("UNKNOWN ERROR");
});
// toThrow 사용
test("test", () => {
expect(() => {
throw new Error("ERROR")
}).toThrow("ERROR")
})
mockReturnValue(value)
const mockFn = jest.fn()
mockFn() // undefined
mockFn(1) // undefined
mockFn.mockReturnValue(1)
mockFn() // 1
mockFn.mockReturnValue('a')
mockFn() // a
mockInplemetation(value)
const mockFn = jest.fn();
mockFn.mockImplementation((name) => `hi ${name}`);
console.log(mockFn('a')); // hi a
const mockFn = jest.fn((name) => `hi ${name}`) // 가능
mockResolvedValue(value) / mockRejectedValue(value)
test('resolve test', async () => {
const mockFn = jest.fn().mockResolvedValue(1);
expect(await mockFn()).toEqual(1);
});
test('reject test', async () => {
const mockFn = jest.fn().mockRejectedValue(new Error('error'));
expect(mockFn()).rejects.toThrow('error');
});
toBeCalled
랑 toHaveBeenCalled
랑 똑같음
toHaveBeenCalled
: mock 함수가 호출 되었는지 확인
toHaveBeenCalledTimes
: 함수가 몇번 호출 되었는지 확인
toHqveBeenCalledWith
: 함수가 특정 인자(props)를 포함해서 호출이 되었는지 확인
jest.fn()과 비슷하지만 그룹을 한꺼번에 모킹 처리할 때 사용한다.
헤당 함수의 호출 여부와 어떻게 호출 되었는지 확인한다.
test('spyOn test', () => {
const calculator = {
add: (a, b) => a + b,
};
const spyFn = jest.spyOn(calculator, 'add');
const result = calculator.add(1, 2);
expect(spyFn).toHaveBeenCalled();
expect(spyFn).toHaveBeenCalledTimes(1);
expect(spyFn).toHaveBeenCalledWith(1, 2);
expect(result).toBe(3);
});
Promise
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Promise
Javascript 동작 원리
https://velog.io/@rnjsrntkd95/Call-Stack-Event-loop-Task-Queue
toBe, toEqual
https://stackoverflow.com/questions/22413009/jasmine-javascript-testing-tobe-vs-toequal
jest promise
https://jestjs.io/docs/asynchronous#asyncawait
jest mock
https://inpa.tistory.com/entry/JEST-📚-모킹-mocking-jestfn-jestspyOn