Mockito在使用doReturn而不是whenThen时未检测到对服务存储库的调用



我对Mocking还很陌生,但我读了很多书,也上过udemy课程(我不是专家,远非如此,只是说我一直在研究这个(,但我仍然想不出什么。

我读过Mockito这篇文章——doReturn((和when((之间的区别,这让我理解了一些事情。

现在让我解释一下我的问题。

我有一个服务impl类,它调用存储库类来获取/执行我想要的任何操作。这个服务类就是我为之编写mockito测试的服务类。

这个问题可以通过两种不同的方式来解决。

第一种方式:(然后返回时(

我有我的测试类,看起来像这样(伪代码(:

serviceImplCastTest {
@Spy
@InjectMocks
ServiceImplClass serviceImplClass;
@Mock
RepositoryClass repositoryClass;
@Test
void whenMethodInService_thenReturnNonEmptyMap() {
List<Class> classList = new ArrayList<~>();
Class class = new Class("Whatever");
classList.Add(class)
Map<String, Class> classMap = classList.stream.collect(Collectors.toMap(Class::getMethod, Function.identity()));
when(serviceImplClass.methodInService()).thenReturn(classMap);
Map<String, Class> actualMap = serviceImplClass.methodInService();
assertFalse(actualMap.isEmpty());
verify(repositoryClass, times(1)).methodInRepository();
}

因此,这不起作用,因为服务中返回映射的方法调用存储库中返回类列表的方法,然后我在服务中的方法将该列表转换为映射,出于某种原因,Mockito期望的是类列表,而不是映射。我得到了Mockito错误类型的返回错误。

(如果服务方法只返回与存储库返回的List类型相同的List,则此代码非常有效。(

第二种方式:(doReturn when(

serviceImplCastTest {
@Spy
@InjectMocks
ServiceImplClass serviceImplClass;
@Mock
RepositoryClass repositoryClass;
@Test
void whenMethodInService_thenReturnNonEmptyMap() {
List<Class> classList = new ArrayList<~>();
Class class = new Class("Whatever");
classList.Add(class)
Map<String, Class> classMap = classList.stream.collect(Collectors.toMap(Class::getMethod, Function.identity()));
doReturn(classMap).when(serviceImplClass).methodInService();
Map<String, Class> actualMap = serviceImplClass.methodInService();
assertFalse(actualMap.isEmpty());
verify(repositoryClass, times(1)).methodInRepository();
}

现在,当使用doReturn-when时,一切都很好,除了验证,repositoryClass.methodInRepository((没有被调用,或者至少没有被正确地监视或其他什么,Mockito抛出错误"被通缉但未被调用";。

所以我不知道如何在Mockito方面解决这个问题,因为一个简单的方法是更改逻辑,服务返回列表而不是映射,然后更改我的应用程序以接收列表并将其映射到那里,但这意味着影响逻辑,我被禁止这样做。

此外,我真的对能够模拟这一点很感兴趣,因为我还有其他一些类似的情况,在这些情况下,我的服务类处理列表,然后将其转换为其他内容,而mocking仍然希望返回一个列表。

我怎么能嘲笑这件事呢?正确的方法是什么?

您在两个代码片段中都犯了同样的错误,因为您正在尝试测试的类中对方法进行存根处理,而不是在模拟类中对该方法进行存根。

这意味着您实际上只是在测试存根,而不是测试类本身。

你想做的是

  1. 去掉间谍注释-你不需要间谍
  2. Stub存储库类的方法,而不是服务类的方法

这样,您将测试服务类是否正确调用存储库类,并正确处理来自存储库类的响应。但您也将绕过存储库类的实现,这就是使用mock的全部意义。

最新更新