我已經使用JMock 2.6.0-RC2編寫了一個單元測試,它使用了幾個包私有類。出於某種原因,這會導致IllegalAccessError
:當訪問JMock中的包私有類時發生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
}
}