팀프로젝트

# 서비스 단위 테스트 코드 작성

KimMZ 2025. 2. 18. 13:07

service 기능이 잘 동작하는지 확인하는 작업입니다.

Mockito는 단위 테스트를 위한 java mocking framework 

 

service 테스트는 repository에 연관되어 있고 DB데이터에 영향을 받는다. DB상태에 따라 다른 결과가 나올 수 있다.

DB사용 없이 테스트하는 것이 어렵고 모호한데 Mock 객체를 사용해서 테스트 하려고 한다.

Mock객체는 가짜 객체로 함수가 실행되면 어떤 결과를 리턴할지 정하는 것이다.

 

gradle 파일에 dependency를 추가 해야 한다.

testImplementation 'org.springframework.boot:spring-boot-starter-test'

 

더보기
더보기
더보기
  • Service
@Slf4j
@Service
@RequiredArgsConstructor
public class PaymentSearchService {

    private final PaymentRepository paymentRepository;
    private final UserRepository userRepository;

    @Transactional(readOnly = true)
    public PaymentResponseDto getPaymentById(UUID paymentId, User user) {

        log.info(paymentId + "의 결제내역 조회 시작");

        // 1. paymentId 확인
        Payment payment = paymentRepository.findById(paymentId)
                .orElseThrow(() -> new IllegalArgumentException("일치하는 결제 내역이 없습니다."));

        User findUser = userRepository.findById(user.getUserId())
                .orElseThrow(()-> new IllegalArgumentException("결제한 회원이 존재하지 않습니다."));

        if(user.getRole() == null || user.getRole() != UserRole.CUSTOMER) {
            throw new AccessDeniedException("CUSTOMER 권한을 가진 사용자만 조회할 수 있습니다.");
        }

        log.info(paymentId + "의 결제내역 조회 종료");

        return new PaymentResponseDto(payment.getPaymentId(), payment.getOrderId()
                , payment.getUserId(), payment.getPaymentStatus()
                , payment.getPaymentAmount(), payment.getPaymentTime());
    }
}

 

  • ServiceTest
@ExtendWith(MockitoExtension.class)
public class PaymentSearchServiceTest {

    @Mock
    private PaymentRepository paymentRepository;

    @Mock
    private UserRepository userRepository;

    @InjectMocks
    private PaymentSearchService paymentSearchService;

    private User user;
    private Payment payment;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this);
        // 테스트 User 객체 생성
        user = new User();
        user.setUserId(UUID.randomUUID());
        user.setRole(UserRole.CUSTOMER);

        // 테스트 Payment 객체 생성
        payment = new Payment();
        payment.setPaymentId(UUID.randomUUID());
        payment.setUserId(user.getUserId());
        payment.setOrderId(UUID.randomUUID());
        payment.setPaymentStatus(PaymentStatus.SUCCESS);
        payment.setPaymentAmount(15900);
    }
	
    @Test
    @Transactional(readOnly = true)
    @DisplayName("paymentId로 결제 조회-1건")
    public void getPaymentIdTest() {
        UUID paymentId = payment.getPaymentId();
        Mockito.lenient().when(paymentRepository.findById(paymentId)).thenReturn(Optional.of(payment));
        Mockito.lenient().when(userRepository.findById(user.getUserId())).thenReturn(Optional.of(user));

        PaymentResponseDto findPayment = paymentSearchService.getPaymentById(paymentId, user);

        Assertions.assertNotNull(findPayment);
        Assertions.assertEquals(paymentId, findPayment.getPaymentId());
    }
}

 

   - 만약, 해당 결제 내역이 없을 경우는 test 실행해도 오류가 발생한다.

  - 현재 POST가 구현되지 않아 조회되지 않는 상태이다.