java - 使用 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(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;
  }
}

我正在使用 Spring Data JPA 存储库,例如:

interface VerificationTokenRepository extends JpaRepository<VerificationToken, Long> {
  void deleteAllByCreatedLessThan(LocalDateTime localDateTime);
}

我的服务如下:

@Service
@AllArgsConstructor
public class VerificationService {

  private VerificationTokenRepository verificationTokenRepository;

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

}

在这个简短的实现之后,我想像下面这样测试它:

@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());
  }
}

问题是,在我的断言中,我在调用方法 removeUnusedVerificationTokens 之后期望大小 3,但毕竟集合大小没有改变,它仍然是 7.

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

Deletes all entities managed by the repository

所以我假设 deleteAll 应该影响整个集合,但事实并非如此。

看似方法应该可以正常工作,但毕竟测试无法证实这一点。对于如何修复上述 Spring Data 查询以达到目标的建议,我将不胜感激。

最佳答案

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

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

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

我建议您阅读一些有关 Mockito 以及模拟和模拟方法如何工作的文章。

关于java - 使用 Spring Data 从存储库中删除对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58644274/

相关文章:

Java 正则表达式使用模式替换文本之间

java - 获得10次方的最快方法

unit-testing - 如何使用Inorder验证调用顺序并返回值?

java - 带有 RoboElectric 私有(private)方法的 PowerMockito 未被 mock

java - ManyToMany - JPA - 如何从映射生成的表中获取数据?

Java在另一个类中创建菜单,添加到框架

java - 使用枚举?

java - 对于只调用 super.method() 的方法,在 junit 中应该检查什么?

spring-boot - @Query 不适用于 QueryDSL 谓词

java - 获取ORA-01722 : invalid number in Spring Data query