[英]Try integration test spring-data-jpa throw MockMVC, but update does not work
我使用 spring-data-jpa 和 spring-boot-web 構建了一個演示應用程序。 我嘗試使用 MockMVC 構建集成測試,它將調用添加接口,然后是修改接口,最后是查詢接口,並確定更改是否生效。 我還使用“spring.jpa.properties.hibernate.show_sql”屬性,打印 sql 登錄控制台。 但是,在控制台中,我只看到了一個insert sql,一個query sql,沒有看到update sql。另外,我使用的@PreUpdate 注解沒有生效,因為覆蓋率檢查顯示沒有執行。
但是當我通過 postman 測試時,一切都非常正常並且符合預期:我看到更新 sql 並且它也執行了@PreUpdate。
編寫測試用例時我做錯了什么?
這是我的測試代碼。 Rest Api 只是調用JpaRepository。
@ExtendWith(SpringExtension.class)
@AutoConfigureMockMvc(addFilters = false)
@SpringBootTest
@Transactional
class TechyoControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@SneakyThrows
@Test
public void should_update_success() {
String createRequest = "{\"name\":\"name_test\",\"money\":12.3}";
MvcResult mvcCreateResult = mockMvc
.perform(MockMvcRequestBuilders.post("/accountItems")
.contentType(MediaType.APPLICATION_JSON)
.content(createRequest))
.andReturn();
AccountItemResponse createResult =
objectMapper.readValue(mvcCreateResult.getResponse().getContentAsString(), AccountItemResponse.class);
// update
String updateRequest = "{" +
" \"name\": \"updated_name\"," +
" \"date\": " + createResult.getTransactionTime().getTime() + "," +
" \"lines\": [{" +
" \"name\": \"line1\"," +
" \"money\": 12" +
" }, {\n" +
" \"name\": \"line1\"," +
" \"money\": 12" +
" }, {\n" +
" \"name\": \"line1\"," +
" \"money\": -12" +
" }]" +
"}";
MvcResult mvcUpdateResult = mockMvc
.perform(MockMvcRequestBuilders.put("/accountItems/" + createResult.getId())
.contentType(MediaType.APPLICATION_JSON)
.content(updateRequest))
.andExpect(status().isOk())
.andReturn();
AccountItemResponse updateResult
= objectMapper.readValue(mvcUpdateResult.getResponse().getContentAsString(), AccountItemResponse.class);
assertThat(updateResult.getId()).isEqualTo(createResult.getId());
assertThat(updateResult.getTransactionTime()).hasSameTimeAs(createResult.getTransactionTime());
assertThat(updateResult.getTotal()).isEqualTo(new BigDecimal("12.00"));
assertThat(updateResult.getAccountItemLines()).hasSize(3);
// query
MvcResult mvcGetResult = mockMvc
.perform(MockMvcRequestBuilders.get("/accountItems/" + createResult.getId()))
.andExpect(status().isOk())
.andReturn();
AccountItemResponse getResult
= objectMapper.readValue(mvcGetResult.getResponse().getContentAsString(), AccountItemResponse.class);
assertThat(getResult.getId()).isEqualTo(createResult.getId());
assertThat(getResult.getTransactionTime()).hasSameTimeAs(createResult.getTransactionTime());
assertThat(getResult.getTotal()).isEqualTo(new BigDecimal("12.00"));
assertThat(getResult.getAccountItemLines()).hasSize(3);
}
}
這是我的實體代碼
@MappedSuperclass
@Getter
@Setter
@RequiredArgsConstructor
@Accessors(chain = true)
public class BasePO {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(updatable = false, nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date createTime;
@Column(nullable = false)
@Temporal(TemporalType.TIMESTAMP)
private Date updateTime;
@PrePersist
protected void prePersist() {
Date now = new Date();
if (createTime == null) {
createTime = now;
}
if (updateTime == null) {
updateTime = now;
}
}
@PreUpdate
protected void preUpdate() {
updateTime = new Date();
}
@PreRemove
protected void preRemove() {
updateTime = new Date();
}
}
@Entity
@Table(name = "account_item")
@Accessors(chain = true)
@Getter
@Setter
@RequiredArgsConstructor
public class AccountItemPO extends BasePO {
@Column(nullable = false)
private String name;
@Column(nullable = false, columnDefinition = "decimal(10,2)")
private BigDecimal totalMoney;
private Date transactionTime;
}
這個集成測試本身並沒有拋出任何異常(因為我返回的數據不包含updateTime等字段)。 程序執行加斷點顯示確實更新了數據,但是create_time/update_time設置為null(雖然我用的是nullable = false)
這是從控制台打印的 sql
Hibernate:
insert
into
account_item
(create_time, update_time, name, total_money, transaction_time)
values
(?, ?, ?, ?, ?)
Hibernate:
select
count(*) as col_0_0_
from
account_item accountite0_
where
accountite0_.id=?
也許你可以試試這個解決方案。 它適用於 Spring Boot 2.7.5(包括 GraphQL)
https://github.com/graphql-java/graphql-java-spring/issues/30#issuecomment-860026650
Handler:
Type = org.springframework.boot.autoconfigure.graphql.servlet.GraphQlWebMvcAutoConfiguration$$Lambda$1547/1627578183 Async:
Async started = true
Async result = org.springframework.web.servlet.function.DefaultEntityResponseBuilder$DefaultEntityResponse@3ec151c5
不知何故,我看到日志說 async = true。 所以我認為關鍵是等待異步完成
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.