java Mockito - 拦截模拟上的任何方法调用

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/10839253/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 02:48:20  来源:igfitidea点击:

Mockito - intercept any method invocation on a mock

javaunit-testingmockito

提问by Karle

Is it possible to intercept all method invocations on a mock in a generic way?

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

Example

例子

Given a vendor provided class such as:

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

public class VendorObject {

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

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

}

I would like to create a mock that re-directs allmethod calls to another class where there are matching method signatures:

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

public class RedirectedToObject {

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

}

The when().thenAnswer() construct in Mockito seems to fit the bill but I cannot find a way to match any method call with any args. The InvocationOnMock certainly gives me all these details anyway. Is there a generic way to do this? Something that would look like this, where the when(vo.*) is replaced with appropriate code:

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.

        }
    }
);

Adding wrappers around the vendor classes to make mocking easy is not an option because:

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

  1. Too large an existing code base.
  2. Part of extremely performance critical applications.
  1. 现有代码库太大。
  2. 极端性能关键应用程序的一部分。

回答by jhericks

I think what you want is:

我想你想要的是:

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.

    }
});

Of course, if you want to use this approach frequently, no need for the Answer to be anonymous.

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

From the documentation: "It's quite advanced feature and typically you don't need it to write decent tests. However it can be helpful when working with legacy systems." Sounds like you.

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