【问题标题】:Mockito - intercept any method invocation on a mockMockito - 拦截模拟上的任何方法调用
【发布时间】:2012-05-31 18:34:17
【问题描述】:

是否可以以通用方式拦截 mock 上的所有方法调用?

示例

给定一个供应商提供的类,例如:

public class VendorObject {

    public int someIntMethod() {
        // ...
    }

    public String someStringMethod() {
        // ...
    }

}

我想创建一个模拟,将 all 方法调用重定向到另一个具有匹配方法签名的类:

public class RedirectedToObject {

    public int someIntMethod() {
        // Accepts re-direct
    }

}

Mockito 中的 when().thenAnswer() 构造似乎符合要求,但我找不到将任何方法调用与任何参数匹配的方法。无论如何,InvocationOnMock 肯定给了我所有这些细节。有没有通用的方法来做到这一点?看起来像这样的东西,其中 when(vo.*) 被替换为适当的代码:

VendorObject vo = mock(VendorObject.class);
when(vo.anyMethod(anyArgs)).thenAnswer(
    new Answer() {
        @Override
        public Object answer(InvocationOnMock invocation) {

            // 1. Check if method exists on RedirectToObject.
            // 2a. If it does, call the method with the args and return the result.
            // 2b. If it does not, throw an exception to fail the unit test.

        }
    }
);

在供应商类周围添加包装器以简化模拟不是一种选择,因为:

  1. 现有代码库太大。
  2. 对性能要求极高的应用程序的一部分。

【问题讨论】:

  • 别告诉我就这么简单 when(vo).thenAnswer(...) :O
  • “性能极其关键的应用程序的一部分。”在这种情况下,添加模拟/代理对象与添加包装器有何不同?您是否有兴趣仅为单元测试或实际应用执行此操作?
  • @mattb:性能方面并不是反对使用包装类的最大理由。我们将创建一个基于原始供应商对象的接口和一个将请求转发到实际供应商对象的实现类。与实际工作的供应商对象相比,此操作的执行时间会很短。更重要的论点是直接使用供应商对象的现有代码库。
  • 听起来像是面向方面编程的工作。

标签: java unit-testing mockito


【解决方案1】:

我想你想要的是:

VendorObject vo = mock(VendorObject.class, new Answer() {
    @Override
    public Object answer(InvocationOnMock invocation) {

        // 1. Check if method exists on RedirectToObject.
        // 2a. If it does, call the method with the args and return the
        // result.
        // 2b. If it does not, throw an exception to fail the unit test.

    }
});

当然,如果你想经常使用这种方法,Answer 不需要匿名。

来自documentation:“这是一个非常高级的功能,通常你不需要它来编写体面的测试。但是在处理遗留系统时它会很有帮助。”听起来像你。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2011-04-04
  • 1970-01-01
  • 1970-01-01
  • 2015-11-04
  • 1970-01-01
  • 1970-01-01
  • 2014-10-11
相关资源
最近更新 更多