2013-02-21 48 views
1

我已經使用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。相關的代碼也顯示在下面(它非常簡潔)。

爲什麼我在測試中看到錯誤?測試類與測試類相同,因此我不希望訪問控制成爲問題。

一些有趣的現象:

  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 
    } 
} 

回答