过去如何设置@CreatedDate(用于测试)

Rob*_*ert 9 testing spring jpa spring-data-jpa

我的spring-data-jpa后端有一个类,它用大量测试数据填充(测试)数据库。该类使用 spring 数据存储库来创建实体。我所有的实体都有一个注释的字段@CreatedData@EntityListeners(AuditingEntityListener.class)模型类上的相应注释。到目前为止,这工作正常。dateCreated 会自动正确设置。

但是在运行Junit 测试时,我有时需要使用过去的 dateCreated 创建一个(测试)对象。我该如何存档?只能通过普通的JDBC?

Rob*_*ert 7

我找到了一种适合我的方法(使用普通 JDBC):

首先,我创建域对象以使用 spring-data-jpa 进行测试:

MyModel savedModel = myRepo.save(myModel);
Run Code Online (Sandbox Code Playgroud)

这会自动用时间戳“now”填充“dateCreated”。由于我需要过去的创建日期进行测试,因此我使用普通 JDBC 手动调整它们:

@Autowired
JdbcTemplate jdbcTemplate;

[...]

// This syntax is for H2 DB.  For MySQL you need to use DATE_ADD
String sql = "UPDATE myTable SET created_at = DATEADD('DAY', -"+ageInDays+", NOW()) WHERE id='"+savedLaw.getId()+"'";
jdbcTemplate.execute(sql);
savedModel.setCreatedAt(new Date(System.currentTimeMillis() - ageInDays* 3600*24*1000);
Run Code Online (Sandbox Code Playgroud)

不要忘记在返回的模型类中也 setCreatedAt 。


小智 7

如果您使用 Spring Boot,您可以模拟 EnableJpaAuditing 注释中使用的 dateTimeProvider bean。Spring Data 使用此 bean 来获取实体创建/修改时的当前时间。

@Import({TestDateTimeProvider.class})
@DataJpaTest
@EnableJpaAuditing(dateTimeProviderRef = "testDateTimeProvider")
public class SomeTest {

    @MockBean
    DateTimeProvider dateTimeProvider;

...
Run Code Online (Sandbox Code Playgroud)

有必要定义实际的 testDateTimeProvider bean,但根本不会使用它,因为您将使用模拟。之后您可以像往常一样编写mockito方法:

@Test
public void shouldUseMockDate() {

    when(dateTimeProvider.getNow()).thenReturn(Optional.of(LocalDateTime.of(2020, 2, 2, 0, 0, 0)));
    
   
   ... actual test assertions ...
Run Code Online (Sandbox Code Playgroud)