1

我使用 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。相关代码也如下所示(相当简洁)。

为什么我在测试中看到错误?测试类与测试类是同一个包的一部分,所以我不认为访问控制是一个问题。

一些有趣的观察:

  1. 如果我更改ExampleInterface为包私有(而不是公共),问题就会消失。可悲的是,在我的现实项目中,这是不可能的。

  2. 仅当我从模拟对象返回值时才会发生异常。下载我的示例项目的人会看到另一个null返回的测试;这个测试通过了。

  3. 如果我将所有类移动到默认包中,则测试通过!如果所有类都保留在 packagefoo中,则测试失败。

以下是我的项目中包含的文件。我在上面链接的 ZIP 是一个包含所有这些的小型 Maven 项目。

我也将这个问题发布到了 JMock 开发者列表中。如果我在那里收到答案,我会更新这个问题(反之亦然)。


失败测试.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
  }
}
4

1 回答 1

0

为未来的读者提供更新......

目前,我认为这是 JMock 中的一个错误。我已经在 J​​Mock github 页面上提交了它:https ://github.com/jmock-developers/jmock-library/issues/43 。还没有回复(也没有对我在邮件列表上的评论)。

我已经切换到Mockito,它能够处理完全相同的情况而不会出错。

于 2013-03-05T09:09:39.860 回答