spring - 如果直接命中端点而不是映射器,如何回滚?
问题描述
我的目标是在控制器测试后回滚更改(在数据库上)。
我做了什么:
- 如果我直接测试 AccountMapper(而不是点击 POST /account/{from_account_number}/transfer),测试将回滚。
预期结果:
- 控制器的测试将在每次测试后回滚更改。
实际结果:
- 控制器的测试没有回滚更改。
对于完整的存储库:https ://github.com/kidfrom/learn-java/tree/main/etc/bankaccount
AccountController.java
package codeassignment.bankaccount.controller;
import codeassignment.bankaccount.mapper.AccountMapper;
import codeassignment.bankaccount.mapper.CustomerMapper;
import codeassignment.bankaccount.model.AccountModel;
import codeassignment.bankaccount.model.GetCurrentBalanceModel;
import codeassignment.bankaccount.model.PostTransferModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import java.math.BigDecimal;
@RestController
@Validated
@RequestMapping("/account")
public class AccountController {
@Autowired
AccountMapper accountMapper;
@PostMapping("/{from_account_number}/transfer")
public ResponseEntity<Object> postTransfer(@PathVariable("from_account_number") @Pattern(regexp = "[0-9]+", message = "uri /account/{from_account_number}/transfer, {from_account_number} must only contain number") String fromAccountNumber, @Valid @RequestBody PostTransferModel requestBody) {
if (fromAccountNumber.equals(requestBody.getTo_account_number())) {
return ResponseEntity.badRequest().body("from_account_number must not be equal to to_account_number");
} else {
if (!accountMapper.exists(requestBody.getTo_account_number())) {
return ResponseEntity.notFound().build();
} else {
BigDecimal currentBalance = accountMapper.getBalance(fromAccountNumber);
if (currentBalance == null) {
return ResponseEntity.notFound().build();
} else if (currentBalance.compareTo(requestBody.getAmount()) < 0) {
return ResponseEntity.status(402).body("Insufficient balance");
} else {
if (accountMapper.updateBalance(currentBalance.subtract(requestBody.getAmount()), fromAccountNumber) != 1) {
return ResponseEntity.status(500).body("Update failed");
} else {
if (accountMapper.addBalance(requestBody) != 1) {
return ResponseEntity.status(500).body("Update failed");
} else {
return new ResponseEntity<>("", HttpStatus.CREATED);
}
}
}
}
}
}
}
AccountMapper.java
package codeassignment.bankaccount.mapper;
import codeassignment.bankaccount.model.AccountModel;
import codeassignment.bankaccount.model.PostTransferModel;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import java.math.BigDecimal;
@Mapper
public interface AccountMapper {
@Select("SELECT customer_number, balance FROM account WHERE account_number=#{accountNumber}")
AccountModel getCustomerNumberAndBalance(String accountNumber);
@Select("SELECT balance FROM account WHERE account_number=#{accountNumber}")
BigDecimal getBalance(String accountNumber);
@Select("SELECT EXISTS(SELECT 1 FROM account WHERE account_number=#{accountNumber})")
boolean exists(String accountNumber);
@Update("UPDATE account SET balance=#{balance} WHERE account_number=#{accountNumber}")
int updateBalance(BigDecimal balance, String accountNumber);
@Update("UPDATE account SET balance=balance+#{amount} WHERE account_number=#{to_account_number}")
int addBalance(PostTransferModel requestBody);
}
AccountControllerTest.java
package codeassignment.bankaccount.controller;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Test;
import org.mybatis.spring.boot.test.autoconfigure.AutoConfigureMybatis;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import java.util.HashMap;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@WebMvcTest
@AutoConfigureMybatis
class AccountControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void postTransferCreated() throws Exception {
HashMap<String, Object> requestBody = new HashMap<>();
requestBody.put("to_account_number", "555002");
requestBody.put("amount", 10000);
mockMvc.perform(
post("/account/555001/transfer")
.contentType(MediaType.APPLICATION_JSON)
.content(new ObjectMapper().writeValueAsString(requestBody)))
.andExpect(status().isCreated());
}
}
解决方案
推荐阅读
- sql - 比较 pl/sql 中的日期
- java - 使用 ConfigProperties 注入对象的 Junit 测试为空
- r - r 中有没有办法使用对象名称的字符列表来改变这些对象与 base::lapply 和 dplyr::mutate
- indexing - 使用数组进行数组索引
- scheme - 如果没有对 Scheme 的下限和舍入函数的先验知识,如何完成 SICP 练习 1.45(制作第 n 个根函数)?
- python - IndexError:使用 For 循环时 Python 3 中的列表索引超出范围
- javascript - 从 C# 在 JavaScript 中生成 Rfc2898DeriveBytes 键
- java - Micronaut JSON 序列化 - 使用 getter 而不是字段
- terraform - Terraform remote-exec 永远创建
- javascript - 在 Angular 中创建允许组件覆盖多个部门的网格系统的想法