带有Mockito 1.9.5的Java 1.8会产生编译错误

时间:2014-07-10 11:47:21

标签: java mockito

切换到Java 1.8之后。 JDK我的一些测试类无法编译。 实现类示例:

import java.util.concurrent.Callable;
import java.util.concurrent.Future;

public class ImplClass {

    public <T> Future<T> executeTask(final Callable<T> task) {
        return null;
    }
}

以下是Mockito的测试课程:

import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import java.util.concurrent.Callable;

import org.junit.Before;

public class TestClass {

    private ImplClass implClassMock;

    @Before
    public void setUp() {
        implClassMock = mock(ImplClass.class);
        when(implClassMock.executeTask(any(Callable.class))).thenReturn(null);
    }
}

我收到错误消息:The method executeTask(Callable<T>) in the type ImplClass is not applicable for the arguments (Callable)

切换回java编译器1.7一切都很好。

知道如何解决此问题吗?

2 个答案:

答案 0 :(得分:11)

从java 8开始,compiler type inference得到了很大的改进。

现在你可以在没有任何编译警告的情况下从匹配器中删除class参数:

when(implClassMock.executeTask(any())).thenReturn(null);

注意:我有相同的编译器故障但只有eclipse。一个bug可能是?

答案 1 :(得分:8)

看起来这是由javac比JLS要求的更灵活引起的。合规性级别为1.8的Eclipse编译器更严格:https://bugs.eclipse.org/bugs/show_bug.cgi?id=430987

@gontard的答案在大多数情况下都有效,但如果您使用不同参数类型覆盖的方法覆盖了javac会让您感到困惑。例如,ExecutorService.submit()将Callable和Runnable都作为参数,你不能用when(executor.submit(any()))然后(...)来模拟它,因为它是不明确的。但明确地参数化这样的类型将使eclipse和javac编译器都很高兴:

when(executor.<Object>submit(any(Callable.class)).then(...)