Я написал модульный тест с использованием JMock 2.6.0-RC2, который использует несколько частных классов пакетов. По некоторым причинам, это вызывает IllegalAccessError
:IllegalAccessError при доступе к частному классу пакета в JMock
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
}
}