Java 从JMock返回ImmutableSet';d对象导致未声明的HrowableException

Java 从JMock返回ImmutableSet';d对象导致未声明的HrowableException,java,jmock,Java,Jmock,下面是我希望通过的单元测试: import static org.junit.Assert.assertEquals; import org.jmock.Expectations; import org.jmock.Mockery; import org.junit.Test; import com.google.common.collect.ImmutableSet; public class JMockTest { @Test public void test() {

下面是我希望通过的单元测试:

import static org.junit.Assert.assertEquals;

import org.jmock.Expectations;
import org.jmock.Mockery;
import org.junit.Test;

import com.google.common.collect.ImmutableSet;

public class JMockTest {

    @Test
    public void test() {
        Mockery mockery = new Mockery();

        final Foo foo = mockery.mock(Foo.class);
        mockery.checking(new Expectations() {{
            oneOf(foo).bar(); will(returnValue(ImmutableSet.<Long>of()));
        }});

        ImmutableSet<Long> result = foo.bar();
        assertEquals(ImmutableSet.<Long>of(), result);
    }

    interface Foo {
        ImmutableSet<Long> bar();
    }

}
导入静态org.junit.Assert.assertEquals;
导入org.jmock.expections;
导入org.jmock.mockry;
导入org.junit.Test;
导入com.google.common.collect.ImmutableSet;
公共类JMockTest{
@试验
公开无效测试(){
嘲弄嘲弄=新嘲弄();
final Foo-Foo=mockry.mock(Foo.class);
嘲弄。检查(新期望(){{
一个(foo.bar();将(returnValue(ImmutableSet.of());
}});
ImmutableSet result=foo.bar();
assertEquals(ImmutableSet.of(),result);
}
接口Foo{
ImmutableSet bar();
}
}
但是,它会抛出以下错误:

java.lang.reflect.UndeclaredThrowableException
    at $Proxy3.bar(Unknown Source)
    at JMockTest$1.<init>(JMockTest.java:17)
    at JMockTest.test(JMockTest.java:16)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:309)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.IllegalAccessException: Class org.jmock.internal.ReturnDefaultValueAction can not access a member of class com.google.common.collect.ImmutableSet with modifiers ""
    at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
    at java.lang.Class.newInstance(Class.java:436)
    at org.jmock.internal.ReturnDefaultValueAction.collectionOrMapInstanceFor(ReturnDefaultValueAction.java:87)
    at org.jmock.internal.ReturnDefaultValueAction.invoke(ReturnDefaultValueAction.java:77)
    at org.jmock.internal.InvocationToExpectationTranslator.invoke(InvocationToExpectationTranslator.java:20)
    at org.jmock.internal.FakeObjectMethods.invoke(FakeObjectMethods.java:38)
    at org.jmock.lib.JavaReflectionImposteriser$1.invoke(JavaReflectionImposteriser.java:33)
    ... 26 more
java.lang.reflect.UndeclaredThrowableException
在$Proxy3.bar(未知来源)
JMockTest$1。(JMockTest.java:17)
在JMockTest.test(JMockTest.java:16)
在sun.reflect.NativeMethodAccessorImpl.invoke0(本机方法)处
位于sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
在sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)中
位于java.lang.reflect.Method.invoke(Method.java:497)
位于org.junit.runners.model.FrameworkMethod$1.runReflectVeCall(FrameworkMethod.java:47)
位于org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
位于org.junit.runners.model.FrameworkMethod.invokeeexplosive(FrameworkMethod.java:44)
位于org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
位于org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)
位于org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
位于org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)
位于org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)
位于org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)
访问org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)
位于org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)
位于org.junit.runners.ParentRunner.run(ParentRunner.java:309)
位于org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
位于org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
位于org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
原因:java.lang.IllegalAccessException:Class org.jmock.internal.ReturnDefaultValueAction无法使用修饰符“”访问com.google.common.collect.ImmutableSet类的成员
在sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)中
位于java.lang.Class.newInstance(Class.java:436)
在org.jmock.internal.ReturnDefaultValueAction.collectionOrMapInstanceFor(ReturnDefaultValueAction.java:87)上
位于org.jmock.internal.ReturnDefaultValueAction.invoke(ReturnDefaultValueAction.java:77)
位于org.jmock.internal.InvocationToExpectationTranslator.invoke(InvocationToExpectationTranslator.java:20)
位于org.jmock.internal.FakeObjectMethods.invoke(FakeObjectMethods.java:38)
位于org.jmock.lib.JavaReflectionImposteriser$1.invoke(JavaReflectionImposteriser.java:33)
... 26多
JMock似乎在内部尝试实例化一个ImmutableSet,尽管我为它提供了一个

请参阅ReturnDefaultValueAction:

private Object collectionOrMapInstanceFor(Class<?> returnType) throws Throwable {
  return returnType.isInterface() ? instanceForCollectionType(returnType) : returnType.newInstance();
}
private Object collectionOrMapInstanceFor(类returnType)抛出可丢弃的{
return returnType.isInterface()?instanceForCollectionType(returnType):returnType.newInstance();
}
returnType.isInterface()
false
b/c它是一个ImmutableSet,所以JMock调用
ImmutableSet.newInstance()
,失败b/c ImmutableSet没有可访问的构造函数

我假设除我之外的其他人曾经模拟过返回guava immutable collection对象的接口,或者是返回没有可见构造函数的类的接口。在JMock你是如何处理这个问题的

编辑:这是JMock2.6.0


EDIT2:这在JMock2.8.2中有效

正如您所描述的,这似乎是JMock 2.6.0版本的一个bug。升级至最新版本,当前为2.8.2。这个问题会消失。

你说得对!我不小心改变了测试。它在2.8.2中确实有效。谢谢你的帮助。克鲁德,如果你不能升级怎么办(