使用 Mockito 将 Class<T> 作为参数的方法存根

2022-08-31 16:23:36

有一个泛型方法将类作为参数,我用Mockito解决它的问题。该方法如下所示:

public <U extends Enum<U> & Error, T extends ServiceResponse<U>> T validate(
    Object target, Validator validator, Class<T> responseClass,
    Class<U> errorEnum);

这太可怕了,至少对我来说是这样...我可以想象没有它的生活,但代码库的其余部分很高兴地使用它......

我打算在我的单元测试中存根此方法以返回一个新的空对象。但是我该如何用 mockito 做到这一点呢?我试过了:

when(serviceValidatorStub.validate(
    any(), 
    isA(UserCommentRequestValidator.class), 
    UserCommentResponse.class, 
    UserCommentError.class)
).thenReturn(new UserCommentResponse());

但是由于我正在混合和匹配匹配器和原始值,因此我得到“org.mockito.exceptions.misusing.InvalidUseOfMatchersException:参数匹配器的无效使用!”


答案 1

问题是,您不能在模拟调用中混合使用参数匹配器和真实参数。所以,宁愿这样做:

when(serviceValidatorStub.validate(
    any(),
    isA(UserCommentRequestValidator.class),
    eq(UserCommentResponse.class),
    eq(UserCommentError.class))
).thenReturn(new UserCommentResponse());

请注意使用参数匹配器来匹配相等。eq()

参见:https://static.javadoc.io/org.mockito/mockito-core/1.10.19/org/mockito/Matchers.html#eq(T)

此外,您可以对类型使用参数匹配器 - 这匹配相同的标识,如Java运算符。same()Class<?>==


答案 2

只是为了在同一线程上完成,如果有人想要存根一个将Class作为参数的方法,但不关心类型,或者需要许多类型以相同的方式进行存根,这是另一种解决方案:

private class AnyClassMatcher extends ArgumentMatcher<Class<?>> {

    @Override
    public boolean matches(final Object argument) {
        // We always return true, because we want to acknowledge all class types
        return true;
    }

}

private Class<?> anyClass() {
    return Mockito.argThat(new AnyClassMatcher());
}

,然后呼叫

Mockito.when(mock.doIt(this.anyClass())).thenCallRealMethod();