Nestjs/jest

테스트케이스 작성시 DRY 원칙_jest

blogger903 2024. 8. 9. 11:38
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를 따라가야해서 검증하는 목적에 어긋난다고 생각합니다