当前位置: 首页 > 知识库问答 >
问题:

用Mockito匹配泛型

吴伟志
2023-03-14

我试图模拟Spring Rest的resttemplate.exchange方法。

在同一个测试中,我有多个调用,它们的不同之处在于返回类型。

// Original method
restTemplate.exchange(UrlMap.SEARCH + '?' + searchDocsForm.toQueryParams(),
            HttpMethod.GET, null, new ParameterizedTypeReference<SearchResultsDTO<SolrDocumentDTO>>() {
            })
// Mock
when(restTemplate.exchange(any(String.class), any(HttpMethod.class), any(), Matchers.<ParameterizedTypeReference<SearchResultsDTO<SolrDocumentDTO>>>any())).thenReturn(
            new ResponseEntity<>(searchResultsDTO, HttpStatus.OK));
// Original method
restTemplate.exchange(UrlMap.ALL_DOCUS_TOPICS,
            HttpMethod.GET, null, new ParameterizedTypeReference<List<SelectItem>>() {
            }).getBody();
// Mock
when(restTemplate.exchange(any(String.class), any(HttpMethod.class), any(), Matchers.<ParameterizedTypeReference<List<SelectItem>>>any())).thenReturn(
            new ResponseEntity<>(selectItems, HttpStatus.OK));

mock不考虑ParameterizedTypereFerence的泛型参数,最后定义的mock胜过前者。

有什么办法能让它起作用吗?

共有1个答案

陆文康
2023-03-14

Mockito本身并不擅长匹配泛型,但您的解决方案比一般情况要容易得多。

替换您的:

Matchers.<ParameterizedTypeReference<SearchResultsDTO<SolrDocumentDTO>>>any())

与:

eq(new ParameterizedTypeReference<SearchResultsDTO<SolrDocumentDTO>>() {}))

首先,matchers.any()与类型不匹配,甚至在其any(foo.class)变体中也不匹配(从Mockito1.x开始)。any()匹配所有值,包括null和包含不正确的类型:

匹配任何对象,包括空值

此方法不使用给定的参数进行类型检查,它只是为了避免在代码中强制转换。然而,在未来的主要版本中,这可能会改变(可以添加类型检查)。

泛型有助于为exchangethenreturn获得正确的参数,但是由于类型擦除,这些类型信息都不能进入类文件,更不用说JVM了。唯一断言其参数类型的匹配器是isa,它接受类文本,对参数化类型没有帮助。

您可以编写一个自定义匹配器来检查参数的类型和类型参数,如果它们不需要擦除的话,但对于您的特定情况,这是不必要的。

类型擦除是ParameterizedTypeReference存在的全部原因:它将泛型信息捕获到子类中,在子类中参数化类型不会被擦除。Guava中的TypeToken或Guice中的TypeLiteral都使用相同的模式。所有这些实现都将参数化类型描述为实例。

因为对相同参数化类型的引用是相等的,所以将Mockito的eq匹配器与不同的引用一起使用,事情应该会很好。

 类似资料:
  • 问题内容: Mockito提供: 如何避免警告,如果需要呢? 问题答案: 对于Java 8及更高版本,很简单: 对于Java 7及更低版本,编译器需要一些帮助。用途:

  • 下面是一个通用搜索算法的实现: 接口: (方括号=弧形括号) 问题出在哪里?我想不通...对泛型参数T也进行了扩展。

  • 问题内容: 有没有办法匹配以下示例例程的任何类参数? 无论传递到哪个类,如何 始终 返回a ?以下尝试仅适用于匹配的特定情况。 编辑 :一种解决方案是 问题答案: 还有两种方法(请参阅我对@Tomasz Nurkiewicz的先前回答的评论): 第一个依据的事实是编译器根本不会让您传递错误的类型: 您会丢失准确的输入(),但可能会按需要使用。 第二个涉及更多,但如果您 确实 要确保to的参数是的或

  • 问题内容: 我正在尝试模拟Spring Rest 的方法。 在同一测试中,我有多个调用,它们的区别仅在于返回类型。 这是我创建的模拟方法 第一 第二 模拟不考虑的通用参数,最后定义的模拟胜过前者。 有什么办法可以使其工作? 问题答案: Mockito并不擅长匹配泛型本身,但是您的解决方案比一般情况要容易得多。 更换: 与: 首先,不匹配类型,甚至不匹配类型(从Mockito 1.x开始)。匹配所有

  • 问题内容: 使用Mockito,我想在其参数列表中使用方法调用,但是我没有找到如何编写该方法的方法。 我只想要像Mockito那样的东西? 问题答案: 我会尝试