Description
테스트코드 리팩터링
우선, 한글을 사용한 멋진 오픈소스 프로젝트에 응원의 글을 남깁니다. 👍
현재 코드에서 아래의 사항을 개선하면 더 멋진 코드가 될 것 같아 issue를 남깁니다. :)
- 테스트 로직과 값 분리.
- each 메서드를 이용한 코드 반복 제거.
- 테스트 관심사별 describe 세분화.
하단에 리팩터링 예시코드를 남겨두었으니 편하게 피드백주시면 감사하겠습니다.
Possible Solution
Current Code
import { chosungIncludes } from './chosungIncludes';
describe('chosungIncludes', () => {
it('should return true when "ㅍㄹㅌ" is entered for searching "프론트엔드"', () => {
expect(chosungIncludes('프론트엔드', 'ㅍㄹㅌ')).toBe(true);
});
it('should return true when "ㅍㄹㅌ" is entered for searching "00프론트엔드"', () => {
expect(chosungIncludes('00프론트엔드', 'ㅍㄹㅌ')).toBe(true);
});
it('should return false when "ㅍㅌ" is entered for searching "프론트엔드"', () => {
expect(chosungIncludes('프론트엔드', 'ㅍㅌ')).toBe(false);
});
it('should return true when "ㅍㄹㅌㅇㄷㄱㅂㅈ" is entered for searching "프론트엔드 개발자"', () => {
expect(chosungIncludes('프론트엔드 개발자', 'ㅍㄹㅌㅇㄷㄱㅂㅈ')).toBe(true);
});
it('should return true when "ㅍㄹㅌㅇㄷ ㄱㅂㅈ" is entered for searching "프론트엔드 개발자"', () => {
expect(chosungIncludes('프론트엔드 개발자', 'ㅍㄹㅌㅇㄷ ㄱㅂㅈ')).toBe(true);
});
// ...codes
});
Step1) it의 each 메서드 사용.
기대 효과:
- 반복코드 제거.
- 하드코딩 된 TestCase 분리.
Refactored
import { chosungIncludes } from './chosungIncludes';
describe('chosungIncludes', () => {
const allTestCases = [
{ search: 'ㅍㄹㅌ', target: '프론트엔드', expected: true },
{ search: 'ㅍㄹㅌ', target: '00프론트엔드', expected: true },
{ search: 'ㅍㄹㅌㅇㄷㄱㅂㅈ', target: '프론트엔드 개발자', expected: true },
{ search: 'ㅍㄹㅌㅇㄷ ㄱㅂㅈ', target: '프론트엔드 개발자', expected: true },
{ search: 'ㅍㅌ', target: '프론트엔드', expected: false },
{ search: '푸롴트', target: '프론트엔드', expected: false },
{ search: 'ㅍㄹㅌㅇㄷ ㄱㅂㅈ', target: ' ', expected: false },
];
it.each(allTestCases)(
'should return $expected when $search is entered for searching $target',
({ search, target, expected }) => {
expect(chosungIncludes(target, search)).toBe(expected);
}
);
});
Step2) 테스트 관심사에 따른 describe 세분화
현재 리팩터링 된 코드는, 하나의 describe 내에서 초성이 포함되어있다고 판단되는 경우
와 초성이 포함되어있다고 판단되지 않는 경우
를 전부 테스트한다는 아쉬움이 있습니다. 이는, 관심사에 따라 describe를 세분화하여 해결할 수 있습니다.
import { chosungIncludes } from './chosungIncludes';
describe('chosungIncludes', () => {
describe('초성이 포함되어있다고 판단되는 경우', () => {
const testCases = [
{ search: 'ㅍㄹㅌ', target: '프론트엔드' },
{ search: 'ㅍㄹㅌ', target: '00프론트엔드' },
{ search: 'ㅍㄹㅌㅇㄷㄱㅂㅈ', target: '프론트엔드 개발자' },
{ search: 'ㅍㄹㅌㅇㄷ ㄱㅂㅈ', target: '프론트엔드 개발자' },
];
it.each(testCases)('should return true when $search is entered for searching $target', ({ search, target }) => {
const result = chosungIncludes(target, search);
expect(result).toBe(true);
});
});
describe('초성이 포함되어있다고 판단되지 않는 경우', () => {
const testCases = [
{ search: 'ㅍㅌ', target: '프론트엔드' },
{ search: '푸롴트', target: '프론트엔드' },
];
it.each(testCases)('should return false when $search is entered for searching $target', ({ search, target }) => {
const result = chosungIncludes(target, search);
expect(result).toBe(false);
});
});
});
Result
etc.
No response