有哪些方法可以测试依赖于静态方法的方法?

时间:2011-04-18 12:31:03

标签: java testing junit mocking

我需要测试一些依赖于Spring Security的安全相关类。此代码使用静态的SecurityContextHolder.getContext()。如何在不设置整个安全上下文的情况下测试调用方法?

我们正在使用JUnit 4和Mockito。 Mockito在常见问题解答中非常清楚,静态方法不受支持。还有其他选择吗? Spring Security案例的答案很好,但我正在寻找更普遍问题的解决方案。

4 个答案:

答案 0 :(得分:7)

看看PowerMock它将允许你模拟静态方法,构造函数以及你通常无法用java做的各种其他疯狂事情。它集成了大多数模拟库,包括mockito(在这里查看http://code.google.com/p/powermock/wiki/MockitoUsage13)。

一般来说,我发现这是一个非常有用的库,可以在你的测试工具箱中(编码java时)。唯一需要注意的是,由于这个库会使用你的字节码,如果你有其他库进行字节码检测/操作,你可能会遇到麻烦,但在你尝试之前你不会知道。

答案 1 :(得分:5)

您可以参考the following issue并注入org.springframework.security.core.context.SecurityContextHolderStrategy实例自Spring Security 3.0以来可用的功能。

答案 2 :(得分:2)

您应该只需在setupt代码中使用模拟SecurityContextHolder.setContext()来呼叫SecurityContext即可。 SecurityContextHolder似乎只是ThreadLocal的一个薄包装,所以应该可以正常工作。

答案 3 :(得分:1)

也许重构代码所以它接受一些接口而不是getContext()?但是,您需要将所有工作委托给上下文的impl。


更新:代码看起来像

interface SecurityContext {
    void foo();
}

class SpringSecurityContext implements SecurityContext {
    public void foo() {
        // call spring static method here
    }
} 

class TestSecurityContext implements SecurityContext {

    public void foo() {
        // test case logic here
    }
}

class SecurityContextClient {
    private final SecurityContext context;

    public SecurityContextClient(SecurityContext context) {
        this.context = context;
    }

    void useSecurity() {
        context.foo();
    }
}