본문 바로가기
스프링

테스트 코드 리팩토링은 필요한가

by 진드윽이 2024. 12. 12.

서론

조회와 생성 기능에 대해서 테스트 코드를 작성 했었고, 수정 기능을 구현 한 후, 수정 기능에 대해서 테스트 코드를 추가로 작성하려고 하던 찰나, 갑자기 어지러움을 느꼈다.

본론

그래서 대충 알고 있던 BeforeEach를 사용해서 맨 처음에 세팅을 한 후, 그 다음 간편하게 테스트코드를 작성하기 위해서 리팩토링을 하려는데

문득 든 생각이 그냥 코드도 아니고.. 테스트 코드 리팩토링이 필요한가? 라는 생각이 들었음.. 비효율적인 것 같은 느낌

테스트 코드 작성 자체가 개발 속도가 느려지는데 리팩토링까지 하면은 더 느려져서 오히려 생산성이 떨어지지 않을까? 라는 의문

  • 원래 코드
  • @SpringBootTest class RecordServiceTest { @Autowired private BookRepository bookRepository; @Autowired private UserRepository userRepository; @Autowired private GroupRepository groupRepository; @Autowired private UserGroupRepository userGroupRepository; @Autowired private RecordRepository recordRepository; @Autowired private RecordService recordService; @Test void 사용자의_그룹에_해당하는_기록_불러오기() { //Given Book book = new Book("김진용의 인생", 456, "image", "김진용", "책설명", "링크url", 5.0); bookRepository.save(book); User user = new User("김진용", "kje@naver.com", "1234", "urlurl"); userRepository.save(user); Group group = new Group(book, null, null, "독서 그룹", "독서를 위한 그룹", 1234L, true, false); groupRepository.save(group); UserGroup userGroup = new UserGroup(user, group, Role.MASTER); userGroupRepository.save(userGroup); Record record1 = new Record(userGroup, "첫 번째 기록", 50); Record record2 = new Record(userGroup, "두 번째 기록", 1000); recordRepository.save(record1); recordRepository.save(record2); //When List<RecordListResponse> records = recordService.viewRecordList(group.getId(), user.getId()); //Then assertEquals(2, records.size()); assertEquals("첫 번째 기록", records.get(0).getText()); assertEquals("두 번째 기록", records.get(1).getText()); } @Test void 사용자의_그룹에서의_기록_생성() { //Given Book book = new Book("김진용의 인생", 456, "image", "김진용", "책설명", "링크url", 5.0); bookRepository.save(book); User user = new User("김진용", "kje@naver.com", "1234", "urlurl"); userRepository.save(user); Group group = new Group(book, null, null, "독서 그룹", "독서를 위한 그룹", 1234L, true, false); groupRepository.save(group); UserGroup userGroup = new UserGroup(user, group, Role.MASTER); userGroupRepository.save(userGroup); //When Long recordId1 = recordService.createRecord(group.getId(), user.getId(), new RequestRecord("나의 기록1", 193)); // Long recordId2 = recordService.createRecord(group.getId(), user.getId(), new RequestRecord("나의 기록2", 389)); Record record = recordRepository.findById(recordId1).orElseThrow(); assertEquals("나의 기록1", record.getText()); assertEquals(193, record.getCurrentPage()); } }
  • 알아본 바 → 필요하다~ 오히려 권장된다고 함.
    1. 가독성:
      • 테스트 의도를 쉽게 파악할 수 있음.
      • 협업 시 다른 팀원도 테스트 코드를 빠르게 이해 가능.
    2. 유지보수성:
      • 공통 로직을 분리하여, 변경이 필요한 경우 최소한의 수정만으로 반영 가능.
    3. 재사용성:
      • @BeforeEach나 별도 메서드로 공통 초기화 코드를 재사용하면 중복을 줄이고, 새 테스트 작성이 용이.
      주의사항
    • 리팩토링 후에도 테스트의 독립성이 유지되도록, 테스트 간 상태 공유를 피해야 함.
    • @BeforeEach에서 공통 데이터를 설정하되, 테스트마다 필요한 추가 설정은 각 테스트 메서드에서 별도로 처리해야함
  • 효율적인 이유(GPT의 주장임, 구글 검색에서는 당연히 다들 리팩토링 하셨음)

결론 - 나의 생각

결국에는 “코드”라면 어떤 종류의 코드이던 간에 리팩토링은 꼭 필요한 것 같다.

테스트 코드도 결국 코드이기 때문에 효율적으로 테스트 하고, 테스트의 의도, 가독성을 위해서 리팩토링이 꼭 필요하다는 것을 느꼈다.

결론2 - 바로 리팩토링

    private BookRepository bookRepository;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private GroupRepository groupRepository;

    @Autowired
    private UserGroupRepository userGroupRepository;

    @Autowired
    private RecordRepository recordRepository;

    @Autowired
    private RecordService recordService;

    private Book book;
    private User user;
    private Group group;
    private UserGroup userGroup;

    @BeforeEach
    void setUp() {
        book = new Book("김진용의 인생", 456, "image", "김진용", "책설명", "링크url", 5.0);
        bookRepository.save(book);

        user = new User("김진용", "kje@naver.com", "1234", "urlurl");
        userRepository.save(user);

        group = new Group(book, null, null, "독서 그룹", "독서를 위한 그룹", 1234L, true, false);
        groupRepository.save(group);

        userGroup = new UserGroup(user, group, Role.MASTER);
        userGroupRepository.save(userGroup);
    }

    @Test
    void 사용자의_그룹에_해당하는_기록_불러오기() {
        //Given
        Record record1 = new Record(userGroup, "첫 번째 기록", 50);
        Record record2 = new Record(userGroup, "두 번째 기록", 1000);
        recordRepository.save(record1);
        recordRepository.save(record2);

        //When
        List<RecordListResponse> records = recordService.viewRecordList(group.getId(), user.getId());

        //Then
        assertEquals(2, records.size());
        assertEquals("첫 번째 기록", records.get(0).getText());
        assertEquals("두 번째 기록", records.get(1).getText());
    }

    @Test
    void 사용자의_그룹에서의_기록_생성() {
        //When
        Long recordId1 = recordService.createRecord(group.getId(), user.getId(), new RequestRecord("나의 기록1", 193));
        Record record = recordRepository.findById(recordId1).orElseThrow();

        //Then
        assertEquals("나의 기록1", record.getText());
        assertEquals(193, record.getCurrentPage());
    }
}

아 하길 잘했다