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

Posted

技术标签:

【中文标题】使用 Mockito 将 Class<T> 作为参数的方法存根【英文标题】:Stubbing a method that takes Class<T> as parameter with Mockito 【发布时间】:2011-03-28 16:29:20 【问题描述】:

有一个将类作为参数的通用方法,我在使用 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:参数匹配器的无效使用!”

【问题讨论】:

我也面临同样的问题,但 eq() 或 same() 对我不起作用。代码是用 Kotlin 编写的。 【参考方案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)

此外,您可以将 same() 参数匹配器用于 Class&lt;?&gt; 类型 - 这匹配相同的标识,例如 == Java 运算符。

【讨论】:

确实如此。但我想知道是否可以改进 Mockito 以允许用户“混合参数匹配器和真实参数”;如果 Unitils Mock 可以做到,那么技术上应该是可行的。【参考方案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();

【讨论】:

【参考方案3】:

不错的@Ash。我用你的通用类匹配器在下面做准备。 如果我们想准备特定类型的模拟,可以使用它。(不是实例)

private Class<StreamSource> streamSourceClass() 
    return Mockito.argThat(new ArgumentMatcher<Class<StreamSource>>() 

        @Override
        public boolean matches(Object argument) 
            // TODO Auto-generated method stub
            return false;
        
    );

用法:

    Mockito.when(restTemplate.getForObject(Mockito.anyString(), 
            **streamSourceClass(),**
            Mockito.anyObject));

【讨论】:

以上是关于使用 Mockito 将 Class<T> 作为参数的方法存根的主要内容,如果未能解决你的问题,请参考以下文章

Mockito的参数匹配

将Mockito与IntelliJ的Java一起使用时出现IllegalStateException

mockito简单教程

如何使用 mockito 捕获特定类型的列表

Mockito.anyString()在Kotlin中与NPE崩溃

Mockito:使用泛型参数进行验证