【问题标题】:Mockito matchers | Correct UsageMockito 匹配器 |正确使用
【发布时间】:2016-02-02 17:42:50
【问题描述】:

Mockito 提供了很多匹配器,例如 any()、anyClass() 等。

人们可以就其用法进行辩论。但我觉得当我们并不真正关心输入对象包含什么时,应该使用匹配器,只要它属于预期的类即可。

我只是想知道这种用法是否正确?如果没有,使用它们的更好方法是什么?

例如:

假设我们有一个预期运行时异常的测试,当使用某个请求对象调用方法时。由于我们在调用 mock 时在此处显式抛出运行时异常,因此请求对象的内容是什么并不重要。所以这个测试看起来合乎逻辑。

@Test(expected = RunTimeException.class)
public void testExceptionOccurs() {
  when(mock.method(any(RequestObject.class))).thenThrow(new RuntimeException());

  mock.method(new RequestObject());
}

这是正确的方法吗?

【问题讨论】:

    标签: junit mockito


    【解决方案1】:

    你是对的,允许 任何给定类型的对象对 Matchers 来说是一个很好的用途,而且你正确地调用了 matchers,但是代码并没有按照你的描述做.

    在 Mockito 1.x 中,any(RequestObject.class) 实际上不会检查参数的类型。它的行为与anyObject() 相同,除了在Java 8 之前,Java 编译器无法推断指定为参数的泛型类型。 改为使用isA(RequestObject.class) 来检查类型。


    Mockito 的默认行为是检查参数是否相等——特别是使用 equals(或 == 用于原始类型)的相等性。我发现any(和anyInt 等)是最有价值的,因为它们完全出于匹配的目的而忽略了一个参数,但是有很多原因你想要覆盖equals 行为使用匹配器:

    • 只检查参数的类型,使用isA
    • equals 定义的更具体地检查实例,例如使用same 检查引用相等
    • 检查参数的属性,例如传递的 bean 的某个属性具有特定值。
    • 通过intThatargThat 等重用Hamcrest 匹配器。

    最后注意:如果您在参数列表中的任何位置使用匹配器或捕获器,请确保为该调用中的每个参数使用一个。 Mockito needs that 1:1 mapping.


    更新: Mockito 提交者Brice 提供了some historical background and future direction

    作为历史参考,anyanything 的简写别名,当时 API 强制转换,贡献者和/或提交者考虑将类作为参数传递以避免这种转换,没有更改此 API 的语义。然而,这个改变最终改变了人们认为这个 API 正在做的事情。 这将在 mockito 2+ 中修复

    【讨论】:

    • 总是使用isA而不是any不是更好吗?
    • @Templar 绝对不是“总是”:isArejects null,这可能不是必要的或不可取的。更重要的是,Mockito 语法默认支持灵活性,以减少响应重构和其他更改的测试脆弱性;参数值通常不太可能具有相关类型但不相关的值(其中any 将涵盖完全不相关的参数,而其他匹配器将涵盖相关值)。
    猜你喜欢
    • 1970-01-01
    • 2020-05-01
    • 1970-01-01
    • 2020-06-30
    • 2013-05-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多