it-swarm.cn

Mockito匹配任何类参数

有没有办法匹配以下示例例程的任何类参数?

class A {
     public B method(Class<? extends A> a) {}
}

我怎样才能 总是 返回一个new B(),无论哪个类被传递到method?以下尝试仅适用于A匹配的特定情况。

A a = new A();
B b = new B();
when(a.method(eq(A.class))).thenReturn(b);

_ edit _ :一个解决方案是

(Class<?>) any(Class.class)
124
Johan Sjöberg

还有两种方法(参见我对@Tomasz Nurkiewicz先前回答的评论):

第一个依赖于编译器根本不会让你传入错误类型的事实:

when(a.method(any(Class.class))).thenReturn(b);

你失去了确切的输入(Class<? extends A>),但它可能正如你所需要的那样工作。

第二个涉及更多,但可以说是更好的解决方案,如果你 真的 想要确保method()的参数是AA的子类:

when(a.method(Matchers.argThat(new ClassOrSubclassMatcher<A>(A.class)))).thenReturn(b);

其中ClassOrSubclassMatcherorg.hamcrest.BaseMatcher,定义如下:

public class ClassOrSubclassMatcher<T> extends BaseMatcher<Class<T>> {

    private final Class<T> targetClass;

    public ClassOrSubclassMatcher(Class<T> targetClass) {
        this.targetClass = targetClass;
    }

    @SuppressWarnings("unchecked")
    public boolean matches(Object obj) {
        if (obj != null) {
            if (obj instanceof Class) {
                return targetClass.isAssignableFrom((Class<T>) obj);
            }
        }
        return false;
    }

    public void describeTo(Description desc) {
        desc.appendText("Matches a class or subclass");
    }       
}

唷!我会选择第一个选项,直到你 真的 需要更好地控制method()实际返回的内容:-)

165
millhouse

没有强制转换还有另一种方法可以做到这一点

when(a.method(Matchers.<Class<A>>any())).thenReturn(b);

此解决方案强制方法any()返回Class<A>类型而不是其默认值(Object)。

42
anmaia

如果您不知道需要导入哪个包:

import static org.mockito.Matchers.any;
any(SomeClass.class)

OR

import org.mockito.Matchers;
Matchers.any(SomeClass.class)
33
Joao Luiz Cadore

怎么样:

when(a.method(isA(A.class))).thenReturn(b);

要么:

when(a.method((A)notNull())).thenReturn(b);
21
Tomasz Nurkiewicz

来自millhouse的解决方案不再适用于最新版本的mockito

此解决方案适用于Java 8和mockito 2.2.9

其中ArgumentMatcherorg.mockito.ArgumentMatcher的实例

public class ClassOrSubclassMatcher<T> implements ArgumentMatcher<Class<T>> {

   private final Class<T> targetClass;

    public ClassOrSubclassMatcher(Class<T> targetClass) {
        this.targetClass = targetClass;
    }

    @Override
    public boolean matches(Class<T> obj) {
        if (obj != null) {
            if (obj instanceof Class) {
                return targetClass.isAssignableFrom( obj);
            }
        }
        return false;
    }
}

并使用

when(a.method(ArgumentMatchers.argThat(new ClassOrSubclassMatcher<>(A.class)))).thenReturn(b);
7
Bertrand Cedric