JMockit / Netbeans - 验证是否调用了AccessController.doPrivileged()

时间:2014-11-05 00:57:22

标签: java netbeans jmockit

我正在使用JMockit 1.12并想要验证是否已调用AccessController.doPrivileged()。这似乎相当简单:

@Test(expected = MissingInvocation.class)
public void testFoo1() {
    foo(false, true);
}

@Test
public void testFoo2() {
    foo(false, false);
}

@Test
public void testFoo3() {
    foo(true, true);
}

private void foo(boolean usePrivilegedAccess, boolean expectAccessControllerCall) {
    new NonStrictExpectations(AccessController.class) {{
    }};

    if (usePrivilegedAccess) {
        AccessController.doPrivileged((PrivilegedAction<String>) () -> "");
    }

    // verify AccessController.doPrivileged was called
    if (expectAccessControllerCall) {
        new Verifications() {{ AccessController.doPrivileged(withAny((PrivilegedAction<Object>) () -> null )); }};
    }
}

请注意,testFoo1()执行而不是调用AccessController.doPrivileged()仍然执行检查。

我添加了这个方法,因为我发现有时即使AccessController.doPrivileged(),Verifications块也会通过。我正在使用Netbeans 8.0.1并经过大量测试,我发现如果我使用“Run Focused Test Method”或“Debug Focused Test Method”(仅运行1次测试)运行测试,那么它就会通过。如果我使用“测试文件”(运行所有测试),则testFoo1()失败,因为它不会抛出MissingInvocation。如果我使用“调试测试文件”(运行所有测试),那么如果我放入一个断点,它总是会失败;如果我没有输入断点,间歇地会失败。很奇怪。

我的JMockit用法是否正确?我是新的,所以任何指针都很受欢迎,但请注意我想从2个测试中运行完全相同的测试代码,这些测试只有一个布尔标志不同。我不想复制/粘贴测试两次。

Netbeans有什么问题吗?

它是否与管道中某处的CGLib注入有关?

1 个答案:

答案 0 :(得分:0)

可能发生的是,在测试期间,AccessController.doPrivileged(...)从其他地方调用,可能来自NetBeans,或者更可能来自JRE本身。

JMockit 1.x不会将AccessController类的模拟仅限于foo(boolean,boolean)方法;相反,它将所有调用注册到其方法,无论它们来自何处。测试必须实现更严格的验证,可能检查传递给模拟方法的确切PrivilegedAction实例,或者甚至通过检查调用堆栈来查看它来自何处。

对于JMockit 2,计划进行API更改,以便模拟仅限于@Tested类,避免这样的情况。