我想创建一个方法,从数据库中删除超过 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 查询以达到目标的建议,我将不胜感激。
最佳答案
这里有多个问题(但是查询方法本身没有任何问题):
您模拟
VerificationTokenRepository
,然后将此模拟对象传递给VerificationService
的构造函数。因此,当您调用其removeUnusedVerificationTokens
方法时,它将调用模拟对象的底层方法,该方法默认情况下绝对不执行任何操作。您为下一次调用
tokenRepository.findAll()
定义一个返回值,该调用返回 7 个对象的列表,然后测试此调用的结果。当然,它返回一个包含 7 个对象的列表,这正是您在上面 3 行中定义的内容。
我建议您阅读一些有关 Mockito 以及模拟和模拟方法如何工作的文章。
关于java - 使用 Spring Data 从存储库中删除对象列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58644274/