いくつかのパッケージ プライベート クラスを利用する 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
返される別のテストが表示されます。このテストはパスします。すべてのクラスをデフォルト パッケージに移動すると、テストに合格します。すべてのクラスが package に残っている場合
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!";
}
}
Class.java の使用
package foo;
class UsingClass {
UsingClass(ExampleInterface exampleInterface) {
PackagePrivateClass bar = exampleInterface.getInstance(); // <--- exception
System.out.println(bar); // originates here
}
}