728x90
환경
jest": "29.7.0"
테스트코드를 작성할때 DRY 원칙에 대해서 정리하려고 합니다
테스트 데이터 생성 - DRY를 엄격히 적용하지 않음
각 테스트 케이스에서 필요한 데이터를 명시적으로 생성하면, 해당 테스트가 어떤 상황을 검증하는지 즉시 파악할 수 있습니다.
테스트 간 독립성을 유지하기 쉽습니다. 한 테스트의 변경이 다른 테스트에 영향을 미칠 가능성이 줄어듭니다.
비즈니스 로직의 변경사항을 테스트 코드에 반영하기가 더 쉽습니다.
Assertion 부분 - DRY 원칙 적용
공통된 검증 로직을 재사용함으로써 코드의 중복을 줄이고 가독성을 높일 수 있습니다.
검증 로직의 변경이 필요할 때 한 곳만 수정하면 되므로 유지보수가 용이합니다.
복잡한 검증 로직을 재사용 가능한 함수로 추출하여 테스트 코드의 의도를 더 명확히 표현할 수 있습니다.
assert 구문에 DRY 적용전
describe('RecipeEstimationResultCommand', () => {
describe('toEntities', () => {
it('should set correct properties for both entities', () => {
const command = new RecipeEstimationResultCommand({
recipeId: 'recipe1',
chefId: 'chef1',
courseId: 'course1',
recipeEstimation: new RecipeEstimation({ id: 'estimation1' }),
});
const entities = command.toEntities();
const [tastingResult, skillProgress] = entities;
// Assertions for tasting result entity
expect(tastingResult.recipeId).toEqual('recipe1');
expect(tastingResult.chefId).toEqual('chef1');
expect(tastingResult.courseId).toEqual('course1');
expect(tastingResult.recipeEstimationId).toEqual('estimation1');
expect(tastingResult.estimationType).toEqual(EstimationTypeEnum.RECIPE);
expect(tastingResult.category).toBe(EstimationCategoryEnum.TASTING_RESULT);
expect(tastingResult.value).toBeNull();
// Assertions for skill progress entity
expect(skillProgress.recipeId).toEqual('recipe1');
expect(skillProgress.chefId).toEqual('chef1');
expect(skillProgress.courseId).toEqual('course1');
expect(skillProgress.recipeEstimationId).toEqual('estimation1');
expect(skillProgress.estimationType).toEqual(EstimationTypeEnum.RECIPE);
expect(skillProgress.category).toBe(EstimationCategoryEnum.SKILL_PROGRESS);
expect(skillProgress.value).toEqual({
data: EstimationResultSkillProgressEnum.MASTERED,
});
});
});
});
assert 구문에 DRY 적용후
describe('RecipeEstimationResultCommand', () => {
describe('toEntities', () => {
it('should set correct properties for both entities', () => {
const command = new RecipeEstimationResultCommand({
recipeId: 'recipe1',
chefId: 'chef1',
courseId: 'course1',
recipeEstimation: new RecipeEstimation({ id: 'estimation1' }),
});
const entities = command.toEntities();
const [tastingResult, skillProgress] = entities;
// Common assertions for both entities
[tastingResult, skillProgress].forEach(entity => {
expect(entity.recipeId).toEqual(command.recipeId);
expect(entity.chefId).toEqual(command.chefId);
expect(entity.courseId).toEqual(command.courseId);
expect(entity.recipeEstimationId).toEqual(command.recipeEstimation.id);
expect(entity.estimationType).toEqual(EstimationTypeEnum.RECIPE);
});
// Specific assertions for tasting result entity
expect(tastingResult.category).toBe(EstimationCategoryEnum.TASTING_RESULT);
expect(tastingResult.value).toBeNull();
// Specific assertions for skill progress entity
expect(skillProgress.category).toBe(EstimationCategoryEnum.SKILL_PROGRESS);
expect(skillProgress.value).toEqual({
data: EstimationResultSkillProgressEnum.MASTERED,
});
});
});
});
예외케이스
- 테스트 데이터가 너무 장황한 경우에는 테스트 픽스쳐로 기본틀을 생성한후 검증하려는 필드만 명시적으로 설정하여 테스트합니다
- assert구문을 function으로 빼는건 오히려 테스트케이스를 파악하는데 depth를 따라가야해서 검증하는 목적에 어긋난다고 생각합니다