Mockito : ArgumentCaptor

김아무개·2023년 5월 16일
0

Spring Boot 🍃

목록 보기
11/95

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


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

ArgumentCaptor 를 사용할 수 있다.


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

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

이런 코드가 있을 때,

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

02번 줄을 보면
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 클래스가 사용됨을 알 수 있었다.

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

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

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

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




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

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

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

화이링

profile
Hello velog! 

0개의 댓글