开发者

What are ways to test methods that depend on static methods?

I need to test some security related classes that depend on Spring Security. This code makes use of SecurityContextHolder.getContext() which is static. How can I test the calling method without setting up an entire security context?

We are using JUnit 4 with Mockito. Mockito was pretty explicit in it's FAQ that static methods where not supported. Is the开发者_如何学Cre an alternative? An answer for the Spring Security case would be nice, but I am looking for a solution to the more general problem.


Have a look at PowerMock it will allow you to mock out static method, constructors and do all sorts of other crazy things you wouldn't normally be able to do with java. It integrates with most mocking libraries including mockito (look here http://code.google.com/p/powermock/wiki/MockitoUsage13 for an example).

In general I've found this to be a very useful library to have in your testing toolbox (when coding java). The only caveat is that since this library plays around with your bytecode, if you have other libraries that do bytecode instrumentation/manipulation you can run into trouble, but you won't know until you try.


You can refer to the following issue and inject org.springframework.security.core.context.SecurityContextHolderStrategy instance which functionality is available since Spring Security 3.0.


You should be able to simply call SecurityContextHolder.setContext() with a mocked SecurityContext in your setupt code. SecurityContextHolder just seems to be a thin wrapper around a ThreadLocal, so it should work fine.


Maybe refactoring code so it accepts some interface instead of getContext()? You'll need impl which will delegate all work to context, though.


UPDATE: Code will look like

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();
    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜