【问题标题】:How to write a matcher that is not equal to something如何编写一个不等于某物的匹配器
【发布时间】:2014-09-26 19:37:12
【问题描述】:

我正在尝试为通话创建模拟。 假设我有这个方法,我正在尝试存根:

class ClassA {
  public String getString(String a) {
    return a + "hey";
  }
}

我想模拟的是: 第一个实例是

when(classA.getString(eq("a")).thenReturn(...);`

在同一个测试用例中

when(classA.getString([anything that is not a])).thenReturn(somethingelse);

第二种情况是我的问题:我如何匹配anyString()而不是“a”?

【问题讨论】:

  • 我认为您可以将答案标记为已接受。

标签: java junit mockito matcher


【解决方案1】:

通过Mockito框架,你可以使用AdditionalMatchers

ClassA classA = Mockito.mock(ClassA.class);
Mockito.when(classA.getString(Matchers.eq("a"))).thenReturn("something"); 
Mockito.when(classA.getString(AdditionalMatchers.not(Matchers.eq("a")))).thenReturn("something else");

希望对你有帮助。

【讨论】:

  • AdditionalMatchers 现在似乎已删除。
  • 嗨@PieterDeBie 我认为 AdditionalMatchers 仍在当前的 Mockito 版本中。 See it on the github project
  • 由于不推荐使用 Matchers,请改用 ArgumentMatchers。另请参阅:zgrepcode.com/mockito/2.24.8/org/mockito/matchers.java
  • 这里有一个值得注意的警告。 AdditionalMatchers::not 的返回类型对于所有数字原语为 0,对于布尔原语为 false,对于所有非原始对象 T 为 null。这意味着当您尝试使用时会遇到丑陋的警告它在参数用 @Nonnull 注释的模拟方法上。
【解决方案2】:

argThat 与 Hamcrest 一起使用:

when(classA.getString(argThat(CoreMatchers.not(CoreMatchers.equalTo("a")))...

您也可以通过订购来做到这一点。如果您将when(anyString)when(eq("a")) 按正确顺序放置,Mockito 应按顺序测试它们并在适当时执行“a”逻辑,否则执行“anyString”逻辑。

【讨论】:

    【解决方案3】:

    在 mockito 中,最后一个存根是最重要的。这意味着您可以简单地使用标准匹配器来满足您的需求:

    // "Default" return values.
    when(classA.getString(ArgumentMatchers.anyString())).thenReturn(somethingelse);
    // Specific return value for "a"
    when(classA.getString(ArgumentMatchers.eq("a"))).thenReturn(something);
    

    请注意,您必须同时使用 ArgumentMatchers,因为您正在混合它们。

    【讨论】:

      【解决方案4】:

      在仔细查看了建议的答案后,我实际上采用了这种方法:

      doAnswer(new Answer<String>() {
        public String answer(InvocationOnMock invocation) throws Throwable {
          String originalParam = (String) invocation.getArguments()[0];
          return StringUtils.equalsIgnoreCase(originalParam, "a") ? "Something" : "Something Else";
        }
      }).when(classA).getString(anyString());
      

      这允许我通过调整参数的返回基数来处理两种以上的情况。

      【讨论】:

      • 这是一个很好的解决方案,但我认为我的和@John B anwers 都更接近您的 OP 要求。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-04-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-12
      相关资源
      最近更新 更多