【问题标题】:Mockito anyMapOf nested genericsMockito anyMapOf 嵌套泛型
【发布时间】:2023-03-12 11:30:02
【问题描述】:

我正在尝试验证是否调用了具有以下签名的方法:

public void process(Map<String, Set<String>> data) {
  ...
}

嵌套的参数化 Set 给我带来了困难。我可以像这样使用 any() 匹配器正确验证它:

verify(dataProcessor).process(Matchers.<Map<String, Set<String>>> any());

Mockito: Verifying with generic parameters 中所述,虽然很烦人,但如果我直接静态导入 Matchers.any 并将其称为:

verify(dataProcessor).process(<Map<String, Set<String>>> any())

但在这种情况下,anyMapOf(clazz, clazz) 似乎是更合适的匹配器。既然你不能做 Set.class 我不确定你会怎么做。由于缺少泛型,以下内容不起作用:

verify(dataProcessor).process(anyMapOf(String.class, Set.class));

是否可以使用 anyMapOf 来验证这种情况,或者我应该坚持使用 Matchers。any()?

【问题讨论】:

  • 你的方法签名已经限制了方法使用的参数类型,你为什么不直接使用any()?不使用Map&lt;String, Set&lt;String&gt;&gt; 调用您的方法的代码甚至不会编译...
  • @fge Java 类型推断不会根据process 中可用的参数类型推断对any 的调用中的类型变量,因为process 可能有重载和/或类型参数它自己的。它在返回值和字段中这样做,因为类型已经明确定义为返回值类型或字段类型。都在the extremely-opaque JLS 15.12.2

标签: java generics mocking mockito


【解决方案1】:

无法使用anyMapOf 来执行此操作。它旨在帮助解决在 Java 7 中将简单类映射到简单类的简单案例,而您的情况比这更复杂。

Java 8 参数推断改进,因此在 Java 8 中,您可以只使用any()

verify(dataProcessor).process(Matchers.any());

除此之外,最好的办法就是像你上面写的那样:

verify(dataProcessor).process(Matchers.<Map<String, Set<String>>>any());

或者通过将匹配器提取到一个静态函数中,它为 Java 提供了足够的信息来自行推断类型:

@Test public void yourTest() {
  // ...
  verify(dataProcessor).process(anyStringSetMap());
}

private static Map<String, Set<String>> anyStringSetMap() {
  return any();
}

(注意:注意anyStringSetMap()的返回值是null;它是side-effect of calling any that you're looking for。提取的方法只是为了通知Java编译器预期的返回类型;注意做任何更花哨的事情都可能会破坏以非常有趣的方式。)

【讨论】:

  • 谢谢杰夫,很高兴得到确认。如果它在这个项目中变得足够普遍,那么也许我会转向新的静态匹配器。
猜你喜欢
  • 2022-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-09
  • 2014-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多