Project
[Toss] 잔액사용(2)
sangyunpark
2023. 8. 24. 13:35
Test코드
TransactionController Test
@WebMvcTest(TransactionController.class)
class TransactionControllerTest {
@MockBean
private TransactionService transactionService;
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Test
public void successUseBalance() throws Exception {
//given
given(transactionService.useBalance(anyLong(), anyString(), anyLong()))
.willReturn(
TransactionDto.builder()
.accountNumber("1234567890")
.transactionType(USE)
.transactionResultType(SUCCESS)
.amount(10000L)
.balanceSnapshot(10000L)
.transactionId("21asfq3qpeu12351cxv")
.transactedAt(LocalDateTime.now())
.build()
);
//when
//then
mockMvc.perform(post("/transaction/use")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(
new UseBalance.Request(1L,"1234567890",1000L)
)))
.andExpect(status().isOk())
.andExpect(jsonPath("$.accountNumber").value("1234567890"))
.andExpect(jsonPath("$.transactionId").value("21asfq3qpeu12351cxv"))
.andExpect(jsonPath("$.transactionResult").value("SUCCESS"))
.andExpect(jsonPath("$.amount").value(10000L))
.andDo(print());
}
}
TransactionService test 코드
성공 case
@ExtendWith(MockitoExtension.class)
class TransactionServiceTest {
@Mock
private AccountRepository accountRepository;
@Mock
private AccountUserRepository accountUserRepository;
@Mock
private TransactionRepository transactionRepository;
@InjectMocks
private TransactionService transactionService;
@Test
@DisplayName("계좌 사용 성공")
public void succesUseBalance() throws Exception {
//given
AccountUser user = AccountUser.builder()
.id(12L)
.name("sy")
.build();
Account account = Account.builder()
.accountUser(user)
.accountStatus(IN_USE)
.accountNumber("1000000012")
.balance(10000L)
.build();
given(accountUserRepository.findById(anyLong())).willReturn(Optional.of(user));
given(accountRepository.findByAccountNumber(anyString())).willReturn(
Optional.of(account)
);
given(transactionRepository.save(any())).willReturn(
Transaction.builder()
.account(account)
.transactionType(USE)
.balanceSnapshot(9000L)
.amount(1000L)
.transactionResultType(SUCCESS)
.transactedAt(LocalDateTime.now())
.build()
);
ArgumentCaptor<Transaction> captor = ArgumentCaptor.forClass(Transaction.class);
//when
TransactionDto transactionDto = transactionService.useBalance(1L, "1000000012", 200L);
//then
verify(transactionRepository, times(1)).save(captor.capture());
assertEquals(200L, captor.getValue().getAmount());
assertEquals(9800L,captor.getValue().getBalanceSnapshot());
assertEquals("1000000012", transactionDto.getAccountNumber());
assertEquals(9000L, transactionDto.getBalanceSnapshot());
assertEquals(1000L,transactionDto.getAmount());
assertEquals(USE,transactionDto.getTransactionType());
assertEquals(SUCCESS,transactionDto.getTransactionResultType());
}
}
실패 case
@Test
@DisplayName("해당 유저가 존재 x - 잔액 사용 실패 ")
public void useBalance_UserNotFound() throws Exception {
//given
AccountUser user = AccountUser.builder()
.id(12L)
.name("sy")
.build();
given(accountUserRepository.findById(anyLong()))
.willReturn(Optional.empty());
//when
AccountException exception = assertThrows(AccountException.class, () -> transactionService.useBalance(1L,"10000000000",3000L));
// exception 발생
//then
assertEquals(ErrorCode.USER_NOT_FOUND, exception.getErrorCode()); // 에러 발생
}
@Test
@DisplayName("해당 계좌가 존재 x - 잔액 사용 실패 ")
public void deleteAccount_AccountNotFound() throws Exception {
//given
AccountUser user = AccountUser.builder()
.id(12L)
.name("sy")
.build();
given(accountUserRepository.findById(anyLong())).willReturn(Optional.of(user));
given(accountRepository.findByAccountNumber(anyString())).willReturn(Optional.empty());
//when
AccountException exception = assertThrows(AccountException.class, () -> transactionService.useBalance(1L,"10000000000",3000L));
// exception 발생
//then
assertEquals(ErrorCode.ACCOUNT_NOT_FOUND, exception.getErrorCode()); // 에러 발생
}
@Test
@DisplayName("계좌 소유주가 다른 경우 - 잔액 사용 실패 ")
public void deleteAccount_UserAccountUnMatch() throws Exception {
//given
AccountUser user = AccountUser.builder()
.id(12L)
.name("sy")
.build();
AccountUser user2 = AccountUser.builder()
.id(13L)
.name("ys")
.build();
given(accountUserRepository.findById(anyLong())).willReturn(Optional.of(user));
given(accountRepository.findByAccountNumber(anyString())).willReturn(Optional.of(Account.builder().accountUser(user2).accountNumber("1000000000").accountStatus(AccountStatus.IN_USE).balance(0L).build())); // 계좌의 유저 아이디 13
//when
AccountException exception = assertThrows(AccountException.class, () -> transactionService.useBalance(1L,"10000000000",3000L));
// exception 발생
//then
assertEquals(ErrorCode.USER_ACCOUNT_UN_MATCH, exception.getErrorCode()); // 에러 발생
}
@Test
@DisplayName("계좌가 이미 해지인 경우 - 잔액 사용 실패 ")
public void deleteAccount_alreadyUnregistered() throws Exception {
//given
AccountUser user = AccountUser.builder()
.id(12L)
.name("sy")
.build();
given(accountUserRepository.findById(anyLong())).willReturn(Optional.of(user));
given(accountRepository.findByAccountNumber(anyString())).willReturn(Optional.of(Account.builder().accountUser(user).accountNumber("1000000000").accountStatus(AccountStatus.UNREGISTERED).balance(0L).build())); // 계좌의 유저 아이디 13
//when
AccountException exception = assertThrows(AccountException.class, () ->transactionService.useBalance(1L,"10000000000",3000L));
// exception 발생
//then
assertEquals(ErrorCode.ACCOUNT_ALREADY_UNREGISTRED, exception.getErrorCode()); // 에러 발생
}
@Test
@DisplayName("거래 금액이 잔액보다 큰 경우")
public void failUseBalance() throws Exception {
//given
AccountUser user = AccountUser.builder()
.id(12L)
.name("sy")
.build();
Account account = Account.builder()
.accountUser(user)
.accountStatus(IN_USE)
.accountNumber("1000000012")
.balance(100L)
.build();
given(accountUserRepository.findById(anyLong())).willReturn(Optional.of(user));
given(accountRepository.findByAccountNumber(anyString())).willReturn(
Optional.of(account)
);
//when
AccountException exception = assertThrows(AccountException.class, () ->transactionService.useBalance(1L,"10000000000",3000L));
//then
assertEquals(ErrorCode.AMOUNT_EXCEED_BALANCE, exception.getErrorCode());
}
@Test
@DisplayName("실패 트랜잭션 저장 성공")
public void saveFailedUseTransaction() throws Exception {
//given
AccountUser user = AccountUser.builder()
.id(12L)
.name("sy")
.build();
Account account = Account.builder()
.accountUser(user)
.accountStatus(IN_USE)
.accountNumber("1000000012")
.balance(10000L)
.build();
given(accountRepository.findByAccountNumber(anyString())).willReturn(
Optional.of(account)
);
given(transactionRepository.save(any())).willReturn(
Transaction.builder()
.account(account)
.transactionType(USE)
.balanceSnapshot(9000L)
.amount(1000L)
.transactionResultType(SUCCESS)
.transactedAt(LocalDateTime.now())
.build()
);
ArgumentCaptor<Transaction> captor = ArgumentCaptor.forClass(Transaction.class);
//when
transactionService.saveFailedUseTransaction( "1000000012", 200L);
//then
verify(transactionRepository, times(1)).save(captor.capture());
assertEquals(200L, captor.getValue().getAmount());
assertEquals(10000L,captor.getValue().getBalanceSnapshot());
assertEquals(FAIL,captor.getValue().getTransactionResultType());
}