【问题标题】:Mockito Java 8 compilation errorsMockito Java 8 编译错误
【发布时间】:2015-02-12 09:37:43
【问题描述】:

我刚迁移到 Java 8,遇到了一些我不知道如何克服的编译错误。

以下代码无法编译:

Mockito.when(
    jdbcTemplate.query(Mockito.eq(expectedQuery1),
        Mockito.any(ResultSetExtractor.class))).thenReturn(mockReturn1);

有错误:

The method query(String, ResultSetExtractor<T>) in the type JdbcTemplate is not 
applicable for the arguments (String, ResultSetExtractor)

我尝试了Java 1.8 with Mockito 1.9.5 gives compile errors的另一种方法:

Mockito.when(jdbcTemplate.query(Mockito.eq(expectedQuery1), Mockito.any()))
    .thenReturn(mockReturn1);

现在我收到以下错误:

The method when(T) in the type Mockito is not applicable for the arguments (void)

这究竟应该如何工作,为什么一开始就不能工作

【问题讨论】:

    标签: java-8 mockito


    【解决方案1】:

    添加类型见证以帮助 Eclipse 编译器解决所有问题:

    Mockito.when(jdbcTemplate.query(Mockito.eq(expectedQuery1),
            Mockito.<ResultSetExtractor<TYPE>> any())).thenReturn(mockReturn1);
    

    确保将 TYPE 替换为 mockReturn1 的类型。例如

    String mockReturn1 = "result";
    
    Mockito.when(jdbcTemplate.query(Mockito.eq(expectedQuery1),
            Mockito.<ResultSetExtractor<String>> any())).thenReturn(mockReturn1);
    

    我希望 Oracle Java 8 编译器能够自行解决这个问题,因为它改进了类型推断功能。

    【讨论】:

    • 当然,当any() 不带参数调用时,您可以这样做。但最初的问题主要是关于调用any() with 参数。您不能为any() 指定一个与您传递给它的参数类型不一致的通用参数。你不能这样做Mockito.&lt;X&lt;Y&gt;&gt;any( X.class )
    • @MikeNakis 我不太明白你的意思。 OP 正在尝试模拟对query() 的调用的适当响应。为了能够返回 T 类型,他必须将调用与 ResultSetExtractor&lt;T&gt;(或者可能是 ResultSetExtractor&lt;? super T&gt;)匹配。
    【解决方案2】:

    发生的情况是您正在传递模拟ResultSetExtractor.class,它的类型为Class&lt;ResultSetExtractor&gt;,但这是不正确的,因为它期待Class&lt;ResultSetExtractor&lt;T&gt;&gt;

    为了克服这个问题,定义一个方法如下:

    @SuppressWarnings( "rawtypes" )
    public static <T> Class<T> uncheckedClassCast( Class clazz )
    {
        if( clazz == null )
            return null;
        @SuppressWarnings( "unchecked" )
        Class<T> result = (Class<T>)clazz;
        return result;
    }
    

    并按如下方式使用:

    Class<ResultSetExtractor<T>> resultSetExtractorClass =
        uncheckedClassCast( ResultSetExtractor.class );
    

    然后,在您对 mockito(或其他任何东西)的调用中使用 resultSetExtractorClass 而不是 ResultSetExtractor.class

    【讨论】:

    • 这里不需要做未经检查的演员表。有关使用类型见证的正确方法,请参阅我的答案。 (虽然我认为这里只有 Eclipse 编译器有问题)。
    • 我不会反对这个答案。尽管 Duncan 的回答更优雅,但我相信您的回答会帮助遇到 mockito 和 java 8 问题并需要更复杂的解决方案的人。
    • @Gleeb 实际上,我的回答适用于您遇到类似问题的任何情况,而不仅仅是 mockito 的这个特定问题。
    • @Gleeb 我的回答收到的反对票可能是 Duncan 遵循此建议中的第 2 项:meta.stackexchange.com/q/17204/175648,许多人认为这在道德上是令人反感的。我本可以对邓肯做同样的事,但我没有。
    • 赞成您像朋友一样解决这个问题:) 感谢您的帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    相关资源
    最近更新 更多