You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cstatm-mte/src/test/java/com/atm/controller/AccountControllerTest.java

300 lines
11 KiB

package com.atm.controller;
import com.atm.model.Account;
import com.atm.model.Customer;
import com.atm.service.AccountService;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
@WebMvcTest(AccountController.class)
public class AccountControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private AccountService accountService;
@Autowired
private ObjectMapper objectMapper;
private Customer testCustomer;
private Account testAccount;
private Account testAccount2;
@BeforeEach
public void setUp() {
testCustomer = new Customer();
testCustomer.setCid(12345L);
testCustomer.setCname("张三");
testCustomer.setCpin("123456");
testCustomer.setCbalance(new BigDecimal("1000.00"));
testCustomer.setCstatus("active");
testCustomer.setCtype("regular");
testAccount = new Account();
testAccount.setAid(1L);
testAccount.setCustomer(testCustomer);
testAccount.setAtype("savings");
testAccount.setAbalance(new BigDecimal("5000.00"));
testAccount.setAstatus("active");
testAccount2 = new Account();
testAccount2.setAid(2L);
testAccount.setCustomer(testCustomer);
testAccount2.setAtype("checking");
testAccount2.setAbalance(new BigDecimal("2000.00"));
testAccount2.setAstatus("active");
}
@Test
public void whenGetAccountById_thenReturnAccount() throws Exception {
// given
when(accountService.findByAid(1L)).thenReturn(Optional.of(testAccount));
// when & then
mockMvc.perform(get("/api/accounts/1"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.aid").value(1))
.andExpect(jsonPath("$.atype").value("savings"))
.andExpect(jsonPath("$.abalance").value(5000.00));
}
@Test
public void whenGetNonExistingAccountById_thenReturnNotFound() throws Exception {
// given
when(accountService.findByAid(999L)).thenReturn(Optional.empty());
// when & then
mockMvc.perform(get("/api/accounts/999"))
.andExpect(status().isNotFound());
}
@Test
public void whenGetAccountsByCustomerId_thenReturnAccounts() throws Exception {
// given
List<Account> accounts = Arrays.asList(testAccount, testAccount2);
when(accountService.findByCid(12345L)).thenReturn(accounts);
// when & then
mockMvc.perform(get("/api/accounts/customer/12345"))
.andExpect(status().isOk())
.andExpect(jsonPath("$").isArray())
.andExpect(jsonPath("$.length()").value(2));
}
@Test
public void whenCreateAccount_thenReturnCreatedAccount() throws Exception {
// given
Account newAccount = new Account();
newAccount.setCustomer(testCustomer);
newAccount.setAtype("investment");
newAccount.setAbalance(new BigDecimal("10000.00"));
newAccount.setAstatus("active");
when(accountService.createAccount(any(Account.class))).thenReturn(newAccount);
// when & then
mockMvc.perform(post("/api/accounts")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(newAccount)))
.andExpect(status().isCreated())
.andExpect(jsonPath("$.atype").value("investment"))
.andExpect(jsonPath("$.abalance").value(10000.00));
}
@Test
public void whenDeposit_thenReturnUpdatedAccount() throws Exception {
// given
BigDecimal depositAmount = new BigDecimal("1000.00");
Account updatedAccount = new Account();
updatedAccount.setAid(1L);
updatedAccount.setCustomer(testCustomer);
updatedAccount.setAtype("savings");
updatedAccount.setAbalance(new BigDecimal("6000.00"));
updatedAccount.setAstatus("active");
when(accountService.deposit(1L, depositAmount)).thenReturn(Optional.of(updatedAccount));
// when & then
mockMvc.perform(post("/api/accounts/1/deposit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"amount\":1000.00}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.aid").value(1))
.andExpect(jsonPath("$.abalance").value(6000.00));
}
@Test
public void whenDepositToNonExistingAccount_thenReturnNotFound() throws Exception {
// given
BigDecimal depositAmount = new BigDecimal("1000.00");
when(accountService.deposit(999L, depositAmount)).thenReturn(Optional.empty());
// when & then
mockMvc.perform(post("/api/accounts/999/deposit")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"amount\":1000.00}"))
.andExpect(status().isNotFound());
}
@Test
public void whenWithdraw_thenReturnUpdatedAccount() throws Exception {
// given
BigDecimal withdrawAmount = new BigDecimal("1000.00");
Account updatedAccount = new Account();
updatedAccount.setAid(1L);
updatedAccount.setCustomer(testCustomer);
updatedAccount.setAtype("savings");
updatedAccount.setAbalance(new BigDecimal("4000.00"));
updatedAccount.setAstatus("active");
when(accountService.withdraw(1L, withdrawAmount)).thenReturn(Optional.of(updatedAccount));
// when & then
mockMvc.perform(post("/api/accounts/1/withdraw")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"amount\":1000.00}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.aid").value(1))
.andExpect(jsonPath("$.abalance").value(4000.00));
}
@Test
public void whenWithdrawFromNonExistingAccount_thenReturnNotFound() throws Exception {
// given
BigDecimal withdrawAmount = new BigDecimal("1000.00");
when(accountService.withdraw(999L, withdrawAmount)).thenReturn(Optional.empty());
// when & then
mockMvc.perform(post("/api/accounts/999/withdraw")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"amount\":1000.00}"))
.andExpect(status().isNotFound());
}
@Test
public void whenWithdrawWithInsufficientBalance_thenReturnBadRequest() throws Exception {
// given
BigDecimal withdrawAmount = new BigDecimal("10000.00");
when(accountService.withdraw(1L, withdrawAmount)).thenReturn(Optional.empty());
// when & then
mockMvc.perform(post("/api/accounts/1/withdraw")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"amount\":10000.00}"))
.andExpect(status().isBadRequest());
}
@Test
public void whenTransfer_thenReturnSuccess() throws Exception {
// given
BigDecimal transferAmount = new BigDecimal("1000.00");
when(accountService.transfer(1L, 2L, transferAmount)).thenReturn(true);
// when & then
mockMvc.perform(post("/api/accounts/1/transfer")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"toAccountId\":2,\"amount\":1000.00}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.message").value("转账成功"));
}
@Test
public void whenTransferWithInsufficientBalance_thenReturnBadRequest() throws Exception {
// given
BigDecimal transferAmount = new BigDecimal("10000.00");
when(accountService.transfer(1L, 2L, transferAmount)).thenReturn(false);
// when & then
mockMvc.perform(post("/api/accounts/1/transfer")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"toAccountId\":2,\"amount\":10000.00}"))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.success").value(false))
.andExpect(jsonPath("$.message").value("转账失败,余额不足"));
}
@Test
public void whenTransferToNonExistingAccount_thenReturnBadRequest() throws Exception {
// given
BigDecimal transferAmount = new BigDecimal("1000.00");
when(accountService.transfer(1L, 999L, transferAmount)).thenReturn(false);
// when & then
mockMvc.perform(post("/api/accounts/1/transfer")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"toAccountId\":999,\"amount\":1000.00}"))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("$.success").value(false))
.andExpect(jsonPath("$.message").value("转账失败,余额不足"));
}
@Test
public void whenGetBalance_thenReturnBalance() throws Exception {
// given
when(accountService.findByAid(1L)).thenReturn(Optional.of(testAccount));
// when & then
mockMvc.perform(get("/api/accounts/1/balance"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.aid").value(1))
.andExpect(jsonPath("$.balance").value(5000.00));
}
@Test
public void whenGetBalanceForNonExistingAccount_thenReturnNotFound() throws Exception {
// given
when(accountService.findByAid(999L)).thenReturn(Optional.empty());
// when & then
mockMvc.perform(get("/api/accounts/999/balance"))
.andExpect(status().isNotFound());
}
@Test
public void whenUpdateAccountStatus_thenReturnSuccess() throws Exception {
// given
when(accountService.updateAccountStatus(1L, "inactive")).thenReturn(true);
// when & then
mockMvc.perform(put("/api/accounts/1/status")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"status\":\"inactive\"}"))
.andExpect(status().isOk())
.andExpect(jsonPath("$.success").value(true))
.andExpect(jsonPath("$.message").value("账户状态更新成功"));
}
@Test
public void whenUpdateStatusForNonExistingAccount_thenReturnNotFound() throws Exception {
// given
when(accountService.updateAccountStatus(999L, "inactive")).thenReturn(false);
// when & then
mockMvc.perform(put("/api/accounts/999/status")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"status\":\"inactive\"}"))
.andExpect(status().isNotFound())
.andExpect(jsonPath("$.success").value(false))
.andExpect(jsonPath("$.message").value("账户不存在"));
}
}