如何在参数不实现 `equals` 的情况下模拟方法调用?

4

我正在为 SystemLoggingService 编写单元测试,并模拟所有对其存储库的调用。 我在使用 SpringJPA 存储库。

@Repository
public interface SystemLoggingRepository extends PagingAndSortingRepository<SystemLogEntity, Long>, JpaSpecificationExecutor<SystemLogEntity> {
}

为了对服务方法findAll(Searchable searchable, Pageable pageable)进行单元测试,我需要模拟存储库方法findAll(Specification<T> spec, Pageable pageable)
正如大家所看到的,Searchable对象在服务逻辑中被转换为JPA Specifications对象。
问题是,我的服务逻辑将传递给存储库方法的JPA的Specifications类没有实现equals()
换句话说,我无法非常精确地模拟存储库方法,因为我必须使用Matchers.any(Specifications.class)
BDDMockito.given(systemLoggingRepository.findAll(Matchers.any(Specifications.class), Matchers.eq(pageRequest))).willReturn(...)

这对于单元测试的质量有多大影响?这是常见做法吗?有没有其他解决方案? Specifications 对象是Spring框架的一个类,不能直接添加 equals()方法。
2个回答

4

您可以尝试使用以下方法捕获规格:

ArgumentCaptor<Specifications> specificationsCaptor = ArgumentCaptor.forClass(Specifications.class);
BDDMockito.given(systemLoggingRepository.findAll(specificationsCaptor.capture(), Matchers.eq(pageRequest))).willReturn(...)

然后验证捕获的值:

Specifications capturedSpecifications = specificationsCaptor.getValue();
assertThat(capturedSpecifications.getSomeProperty(), ... )

您可以在这里找到更多信息:https://static.javadoc.io/org.mockito/mockito-core/2.8.47/org/mockito/Mockito.html#15


2
除了@VolodymyrPasechnyk的答案之外,你可能会考虑将创建Specifications对象的责任提取到一个单独的类中,这将成为您CUT的另一个依赖项

是的,这是一个想法。目前我不知道如何测试这个创建过程,但它已经被标记为一个问题。 - Herr Derb
是的,这很有道理。如果我这样做,我也可以使用类类型匹配器Matchers.any(Specifications.class)进行模拟而不会出现任何问题。我看得对吗? - Herr Derb
@HerrDerb 我同意。你甚至可以配置新的依赖项返回 Specifications 的模拟对象,然后验证这个具体的对象是否被传递... - Timothy Truckle
@HerrDerb 只要你的代码能够完成它应该完成的任务,就没有所谓的“对”或“错”,只有“合适”和“不合适”... ;o) - Timothy Truckle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接