【发布时间】:2020-12-02 11:02:19
【问题描述】:
我有一个简单的实体,它要求最后修改时间应该在持久时更新。
@Data // Lombok thing
@Entity
@Table(name = "MY_ENTITY")
public class MyEntity {
@Column(name = "LAST_MODIFIED", nullable = false)
private LocalDateTime lastModified;
// irrelevant columns including id omitted
@PrePersist
public void initializeUUID() {
lastModified = LocalDateTime.now();
}
}
我需要实现一个查询这些实体的作业早于特定时间(比方说一天),修改其状态并将它们持久化。我在为涵盖此类用例的单元测试创建数据时遇到问题。
虽然我手动设置了lastModified 时间,但@PrePersist 会导致其更改,无论设置值如何。
@Autowired // Spring Boot tests are configured against in-memory H2 database
MyEntityRepository myEntityRepository;
var entity = new MyEntity();
entity.setLastModified(LocalDateTime.now().minusDays(3));
myEntityRepository.entity(entity);
问题:如何准备预先保存的数据 (lastModified) 而不为了单元测试而大幅修改 MyEntity 类?欢迎使用 Mockito 的解决方案。
注意我使用 Spring Boot + jUnit 5 + Mockito
我尝试过的事情:
-
How to mock persisting and Entity with Mockito and jUnit: 模拟持久化实体不是一种方法,因为我需要将实体持久化在 H2 中以进行进一步检查。此外,我尝试使用 spy bean 使用这个技巧 Spring Boot #7033 获得相同的结果。
-
Hibernate Tips: How to activate an entity listener for all entities:使用为单元测试范围配置的静态嵌套类
@TestConfiguration以编程方式添加侦听器。这个东西根本没有被调用。@TestConfiguration public static class UnitTestConfiguration { // logged as registered @Component public static class MyEntityListener implements PreInsertEventListener { @Override public boolean onPreInsert(PreInsertEvent event) { // not called at all Object entity = event.getEntity(); log.info("HERE {}" + entity); // no log appears // intention to modify the `lastModified` value return true; } } -
肮脏的方式:使用“覆盖”
lastModified值的@PrePersist创建一个扩展MyEntity的方法级类。结果为org.springframework.dao.InvalidDataAccessApiUsageException。为了解决这个问题,这样的实体依赖于@Inheritance注释 (JPA : Entity extend with entity),我不想仅仅为了单元测试而使用它。实体不得在生产代码中扩展。
【问题讨论】:
-
您可以选择使用 Spring 的AuditingEntityListener 吗?似乎很适合您的用例。然后,您可以在测试配置中提供替代的
auditingDateTimeProviderbean。 -
@wjans:我从来没有听说过这个,我一定会看看并试一试。你能给我这个东西的示例用法吗(最好是答案)?
-
@priyranjan:我偶然发现了这个问题。只要我不使用依赖项来设置
lastModified值,它就没有提供实现此目的的方法。此外,如果我错了,请纠正我,JMockit 是另一个依赖项,我并不热衷于仅将它包含在一个测试中(我使用 Spring + jUnit 5 + Mockito 组合)。
标签: java spring spring-boot spring-data-jpa spring-test