Java 使用Spring数据从存储库中删除对象列表

Java 使用Spring数据从存储库中删除对象列表,java,junit,spring-data-jpa,spring-data,Java,Junit,Spring Data Jpa,Spring Data,我想创建一个方法,从数据库中删除超过30分钟的VerificationToken对象。 VerificationToken.class看起来像: @Builder @AllArgsConstructor class VerificationToken extends AbstractBaseEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(uniq

我想创建一个方法,从数据库中删除超过30分钟的
VerificationToken
对象。
VerificationToken.class
看起来像:

@Builder
@AllArgsConstructor
class VerificationToken extends AbstractBaseEntity {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @Column(unique = true)
  private String value;

  @Column(unique = true)
  private String email;

  @CreatedDate private LocalDateTime created;

  VerificationToken() {}

  VerificationToken(String value, String email) {
    this.value = value;
    this.email = email;
  }

  public Long getId() {
    return id;
  }

  String getValue() {
    return value;
  }

  public String getEmail() {
    return email;
  }

  LocalDateTime getCreated() {
    return created;
  }
}
@Service
@AllArgsConstructor
public class VerificationService {

  private VerificationTokenRepository verificationTokenRepository;

  void removeUnusedVerificationTokens(LocalDateTime localDateTime) {
    verificationTokenRepository.deleteAllByCreatedLessThan(localDateTime.minusMinutes(30));
  }

}
我使用的Spring数据JPA存储库如下:

interface VerificationTokenRepository extends JpaRepository<VerificationToken, Long> {
  void deleteAllByCreatedLessThan(LocalDateTime localDateTime);
}
在这个简短的实现之后,我想对其进行如下测试:

@ExtendWith(MockitoExtension.class)
class VerificationServiceTest {

  @InjectMocks
  private VerificationService verificationService;

  @Mock
  private VerificationTokenRepository tokenRepository;


  @BeforeEach
  void setUp() {
    verificationService = new VerificationService(tokenRepository);
  }

  @Test
  void removeUnusedVerificationTokens() {

    //given
    given(tokenRepository.findAll()).willReturn(verificationTokenDataStab());
    //when
    verificationService.removeUnusedVerificationTokens(LocalDateTime.now().minusMinutes(30));
    //then
    assertAll(() -> assertEquals(tokenRepository.findAll().size(), 3));

  }

  List<VerificationToken> verificationTokenDataStab() {
    return
        List
            .of(
                VerificationToken.builder().created(LocalDateTime.now().minusMinutes(65)).build(),
                VerificationToken.builder().created(LocalDateTime.now().minusMinutes(22)).build(),
                VerificationToken.builder().created(LocalDateTime.now().minusMinutes(200)).build(),
                VerificationToken.builder().created(LocalDateTime.now().minusMinutes(90)).build(),
                VerificationToken.builder().created(LocalDateTime.now().minusMinutes(10)).build(),
                VerificationToken.builder().created(LocalDateTime.now().minusMinutes(5)).build(),
                VerificationToken.builder().created(LocalDateTime.now().minusMinutes(35)).build());
  }
}
@ExtendWith(MockitoExtension.class)
类验证服务测试{
@注射模拟
私有验证服务验证服务;
@嘲弄
私有验证存储库令牌存储库;
@之前
无效设置(){
verificationService=新的verificationService(令牌存储库);
}
@试验
void removeUnusedVerificationTokens(){
//给定
给定(tokenRepository.findAll()).willReturn(verificationTokenDataStab());
//什么时候
verificationService.removeUnusedVerificationTokens(LocalDateTime.now().minusMinutes(30));
//然后
assertAll(()->assertEquals(tokenRepository.findAll().size(),3));
}
列表验证KenDataStab(){
返回
列表
.的(
VerificationToken.builder().created(LocalDateTime.now().Minutes(65)).build(),
VerificationToken.builder().created(LocalDateTime.now().Minutes(22)).build(),
VerificationToken.builder().created(LocalDateTime.now().Minutes(200)).build(),
VerificationToken.builder().created(LocalDateTime.now().Minutes(90)).build(),
VerificationToken.builder().created(LocalDateTime.now().minusMinutes(10)).build(),
VerificationToken.builder().created(LocalDateTime.now().Minutes(5)).build(),
创建(LocalDateTime.now().minusMinutes(35)).build());
}
}
问题是,在我的断言中,我期望调用方法后的大小
3
removeUnusedVerificationTokens,但毕竟集合大小没有改变,仍然是
7

根据文件,方法:
void deleteAll()
来自CrudRepository

删除存储库管理的所有实体

因此,我假设
deleteAll
会影响整个集合,但事实并非如此


表面上看,这种方法应该能正常工作,但毕竟,测试无法证实这一点。对于如何修复上述Spring数据查询以实现目标的建议,我将不胜感激

这里有多个问题(但是查询方法本身没有任何问题):

  • 模拟
    VerificationTokenRepository
    ,然后将此模拟对象传递给
    VerificationService
    的构造函数。因此,当您调用其
    removeUnusedVerificationTokens
    方法时,它将调用模拟对象的基线方法,默认情况下,该方法不执行任何操作

  • 为下一次调用
    tokenRepository.findAll()
    定义一个返回值,该调用返回7个对象的列表,然后测试此调用的结果。当然,它会返回一个包含7个对象的列表,这正是上面3行定义的


  • 我建议您阅读一些关于Mockito的文章,以及mocks和mocked方法是如何工作的。

    您能否尝试用deleteByCreatedLessThan替换deleteAllByCreatedLessThan?此外,还应该在属性文件中添加:spring.jpa.show sql=true logging.level.org.hibernate.sql=DEBUG logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE,以查看答案的实际查询库。你能建议一种方法来测试这种特殊的方法吗?由于该方法是void类型,我只能检查是否调用了该方法,或者是否有不同的机会来验证Spring数据方法是否符合其假设?您只能通过集成测试对其进行测试。在测试过程中,将一些数据放入内存数据库,调用该方法,然后检查是否从数据库中删除了相应的条目。