【发布时间】:2013-02-21 15:27:23
【问题描述】:
我使用 JMock 2.6.0-RC2 编写了一个单元测试,它使用了几个包私有类。出于某种原因,这会导致 IllegalAccessError:
java.lang.IllegalAccessError: tried to access class foo.PackagePrivateClass from class $Proxy6
at $Proxy6.getInstance(Unknown Source)
at foo.UsingClass.<init>(UsingClass.java:6)
at foo.FailingTest.testFailure(FailingTest.java:29)
我已将一个演示该问题的最小 Maven 项目上传到此处:http://dl.dropbox.com/u/108474287/example-project.zip。相关代码也如下所示(相当简洁)。
为什么我在测试中看到错误?测试类与测试类属于同一个包,所以我认为访问控制不会成为问题。
一些有趣的观察:
如果我将
ExampleInterface更改为包私有(而不是公共),问题就会消失。可悲的是,在我的现实项目中,这是不可能的。仅当我从模拟对象返回值时才会发生异常。下载我的示例项目的人会看到另一个返回
null的测试;此测试通过。如果我将所有类移到默认包中,则测试通过!如果所有类都保留在包
foo中,则测试失败。
以下是我的项目中包含的文件。我上面链接的 ZIP 是一个包含所有这些的小型 Maven 项目。
我也已将此问题发布到 JMock 开发人员列表中。如果我在那里收到答案,我会更新这个问题(反之亦然)。
FailingTest.java
package foo;
// Imports omitted
@RunWith(JMock.class)
public class FailingTest {
private static final PackagePrivateClass EXAMPLE_INSTANCE =
new PackagePrivateClass();
public Mockery context = new JUnit4Mockery();
@Test
public void testFailure() {
final ExampleInterface exampleInterface = context
.mock(ExampleInterface.class);
context.checking(new Expectations() {
{
oneOf(exampleInterface).getInstance();
will(returnValue(EXAMPLE_INSTANCE));
}
});
new UsingClass(exampleInterface); <-- exception thrown from constructor
}
}
ExampleInterface.java
package foo;
public interface ExampleInterface {
PackagePrivateClass getInstance();
}
PackagePrivateClass.java
package foo;
class PackagePrivateClass {
PackagePrivateClass() {}
@Override
public String toString() {
return "Hello, World!";
}
}
UsingClass.java
package foo;
class UsingClass {
UsingClass(ExampleInterface exampleInterface) {
PackagePrivateClass bar = exampleInterface.getInstance(); // <--- exception
System.out.println(bar); // originates here
}
}
【问题讨论】: