Today
-
Yesterday
-
Total
-
  • Mockito : ArgumentCaptor
    Spring Boot 🍃 2023. 12. 1. 00:01

    Mockito🍸의 mocking에 사용되는 클래스이다.

    메서드 호출에 사용되는 인자에 대해서 검증하고 싶을 때,

    ArgumentCaptor 를 사용할 수 있다.

    과제 프로젝트에 사용된 부분을 가져와서 본다면

    // given
    ArgumentCaptor<Transaction> captor = ArgumentCaptor.forClass(Transaction.class);
     
    // when
    transactionService.saveFailedUseTransaction("1000000000", USE_AMOUNT);
     
    // then
    verify(transactionRepository, times(1)).save(captor.capture());
    assertEquals(USE_AMOUNT, captor.getValue().getAmount());
    assertEquals(10000L, captor.getValue().getBalanceSnapshot());
    assertEquals(F, captor.getValue().getTransactionResultType());

    이런 코드가 있을 때,

    02번 줄로 보아 , Transaction 클래스가 //when에서 사용할 메서드의 매개변수로 사용 되고

    05번 줄을 보면 transactionService에서 saveFailedUseTransaction() 메서드에 Transaction 클래스가 사용되는 것 같다.

    saveFailedUseTransaction 메서드를 뜯어보면

    @Transactional
    public void saveFailedUseTransaction(String accountNumber, Long amount) {
        Account account = accountRepository.findByAccountNumber(accountNumber)
                .orElseThrow(() -> new AccountException(ACCOUNT_NOT_FOUND));
     
        saveAndGetTransaction(F, account, amount);
    }

    이렇게 생겼는데, 여기선 Transaction 클래스를 볼 수 없으니 메서드 내부에 작성된 saveAndGetTransaction() 메서드도 뜯어본다면!

    private Transaction saveAndGetTransaction(TransactionResultType transactionResultType, Account account, Long amount) {
        return transactionRepository.save(
                Transaction.builder()
                        .transactionType(USE)
                        .transactionResultType(transactionResultType)
                        .account(account)
                        .amount(amount)
                        .balanceSnapshot(account.getBalance())
                        .transactionId(UUID.randomUUID().toString().replace("-", ""))
                        .transactedAt(LocalDateTime.now())
                        .build()
        );
    }

    여기에서 transactionRepository의 save()메서드 인자로 Transaction 클래스가 사용됨을 알 수 있었다.

     

    그리고 08번 줄의 코드를 보면 verify().save(captor.capture()) 라고 적혀있는 것을 볼 수 있는데,

    이게 Transaction 클래스가 직접적으로 사용 된 saveAndGetTransaction() 메서드의 return에 작성되어 있는 transactionRepository 클래스의 save() 메서드에 사용된 Transaction 클래스(captor된 부분)를 검증하는 것이다.

    이게 로직 상 한번만 실행되어야 하는 중요한 부분이기 때문에 먼저 verify( ... , times(1)).save(captor)를 사용해서 1회만 실행되는지를 검증하고 1회 실행됨이 검증되면

    그 다음으로 9~11번 줄에서 captor로 잡힌 데이터의 정확성을 검증하는 부분인 것이었다.


    아 이게 로직이 진짜 복잡하다는 생각을 했다.

    a b c 배우다가 회화 배우는 기분

    코드의 흐름을 확실히 알아야 공부를 할 수 있을 것 같다.

    화이링

Designed by Tistory / Custom by 얼거스