[英]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.