2013-02-21 2 views
1

Я написал модульный тест с использованием 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. Соответствующий код также показан ниже (он довольно краток).

Почему я вижу ошибку в своем тесте? Класс тестирования является частью того же пакета, что и тестируемые классы, поэтому я не ожидал, что проблема с доступом будет проблемой.

Некоторые интересные наблюдения:

  1. Если я изменить ExampleInterface быть пакет частных (а не государственных), эта проблема уходит. К сожалению, в моем реальном проекте это не возможно.

  2. Исключение происходит только в том случае, если я возвращаю значение из моего макета. Те, кто загрузит мой пример проекта, увидят еще одно испытание, в котором возвращается null; этот тест проходит.

  3. Если я переведу все классы в пакет по умолчанию, тесты проходят! Если все классы остаются в пакете 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 
    } 
} 

ответ

0

Для обеспечения обновления для будущих читателей ....

В настоящее время, я считаю, что это ошибка в JMock. Я разместил его на странице JMock github: https://github.com/jmock-developers/jmock-library/issues/43. Пока нет ответов (и на мой комментарий к списку рассылки).

С тех пор я перешел на Mockito, который способен обрабатывать точно такую ​​же ситуацию без ошибок.