[Connecti] TDD 적용 - 로그인 테스트

CosmoNumb·2024년 11월 1일

TDD 진행 중 작성한 로그인 성공 테스트 과정 기록

로그인 성공을 테스트하기 위해 다음과 같이 코드를 작성했지만, encoder.matches(...) 부분에서 에러가 발생함

@Test
@DisplayName("로그인 성공: 올바른 사용자명과 비밀번호")
void testUserLoginSuccess() {
    // 테스트에 필요한 사용자 정보를 설정
    String userName = "testuser";
    String password = "password";

    // Fixture로 테스트용 가짜 UserEntity 생성
    UserEntity fixture = UserEntityFixture.get(1L, userName, password);

    // Mocking 설정
    when(userEntityRepository.findByUserName(userName)).thenReturn(Optional.of(fixture));

    // 실제 메서드 실행 및 성공 여부 검증
    Assertions.assertDoesNotThrow(() -> userService.login(userName, password));
}

이 코드에서는 userEntityRepository.findByUserName(userName)의 결과를 Mocking하여 fixture를 반환하도록 했으나, 테스트가 여전히 실패함


-> 이슈 해결 : encoder.matches(...) 부분을 추가로 Mocking 하는 코드를 추가 (encoder.matches(...) 부분에서 실제 비밀번호 비교가 이루어지지 않아 에러가 발생한 것으로 파악)

encoder.matches(...)는 비밀번호를 비교하는 메서드로, 로그인 시 사용자가 입력한 비밀번호와 DB에 저장된 인코딩된 비밀번호를 비교하지만,테스트 환경에서는 입력 비밀번호와 암호화된 비밀번호의 일치 여부를 파악할 필요가 없음.
그러므로, 비밀번호가 일치한다고 가정하는 상황을 만들어주어야 테스트가 원활하게 진행되며,

이를 위해 encoder.matches(...)를 다음과 같이 기존 코드에 추가로 Mocking하여 항상 true를 반환하도록 설정. (mocking 의도 : 로그인 성공을 위한 테스트의 조건을 간단하게 만들기 위함 ~ Mocking으로 특정 결과를 반환하도록 설정한다.)

(추가한 코드)

when(encoder.matches(password, fixture.getPassword())).thenReturn(true);

(정리)

  1. 이 Mocking 설정이 없을 경우, encoder.matches(...)는 실제로 비밀번호를 비교하는데, 테스트에서는 이 과정이 불필요하고, 실제 암호화된 비밀번호가 없으므로 비밀번호 비교가 항상 실패하여 테스트가 실패하게 되는 것이다.

  2. Mocking 추가 후: encoder.matches(...)true를 반환하도록 설정하여, userService.login(...) 메서드는 비밀번호가 일치한다고 가정하고 테스트가 통과됨


수정 후 정상 로그인 테스트를 통과한 코드

@Test
@DisplayName("로그인 성공: 올바른 사용자명과 비밀번호")
void testUserLoginSuccess() {

    // 테스트에 필요한 사용자 정보를 설정
    String userName = "testuser";
    String password = "password";

    // Fixture로 테스트용 가짜 UserEntity 생성
    UserEntity fixture = UserEntityFixture.get(1L, userName, password);

    // Mocking 설정
    when(userEntityRepository.findByUserName(userName)).thenReturn(Optional.of(fixture));
    when(encoder.matches(password, fixture.getPassword())).thenReturn(true); // 추가된 Mocking 설정

    // 실제 메서드 실행 및 성공 여부 검증
    Assertions.assertDoesNotThrow(() -> userService.login(userName, password));
}

0개의 댓글