Disclaimer I am not a Mockito user, but from what I understand, the mockery is used for situations where you introduced dependent classes (fields) and you mocked these dependencies. In this case, you still need to set the field with the mocked object. for instance
public class TestClass { TestService testService; public void doTest() { System.out.println(testService.getString()); } public void setTestService(TestService testService) { this.testService = testService; } } public class TestService { public String getString() { return "Hello world"; } } @Test public void toTest() { TestService testService = Mockito.mock(TestService.class); Mockito.when(testService.getString()).thenReturn("Hello Squirrel"); TestClass testClass = new TestClass(); testClass.setTestService(testService); testClass.doTest(); }
You can see that we are installing TestService in TestClass with the mocked object. This is not the biggest example, since we could just create an instance of TestService , but from my understanding, as I understand it, what should be done should work.
As I said, I donโt see how this can be done with the AuthorizationRequestFilter , since it is processed by the test container, and we do not create it for unit test. Even if we were seemingly intrusive (and redundant) add a SecurityContext field.
Thus, without a full integration test, when we start the server, and using the authentication capabilities of the server, it will be difficult to handle the SecurityContext for this use-case, since the SecurityContext is created by the container, receiving information from the authentication mechanism of containers with servlets.
One way to achieve this (although IMO does not look very elegant, but works), without a full integration test, is to create an aa filter that runs before your AuthorizationRequestFilter and set the SecurityContext from there. Testing aside, this is actually quite common in cases where we need to implement our own authentication mechanism.
An example of how you can do this for your unit test might be something like:
public class UrlerResourceTest extends JerseyTest { ... @Override public Application configure() { return new ResourceConfig(FooResource.class) .register(AuthorizationRequestFilter.class) .register(AuthenticationFilter.class); } @Provider @Priority(Priorities.AUTHENTICATION) public static class AuthenticationFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) throws IOException { requestContext.setSecurityContext(new SecurityContext() { @Override public Principal getUserPrincipal() { return new Principal() { @Override public String getName() { return "Stackoverflow"; } }; } @Override public boolean isUserInRole(String string) { return "privileged".equals(string); } @Override public boolean isSecure() { return true; } @Override public String getAuthenticationScheme() { return "BASIC"; } }); } } ... }
This filter will be executed before the AuthorizationRequestFilter due to the @Priority annotation. We set it to Priorities.AUTHENTICATION , which will be in front of any other filter without such an annotation. (See API Priorities and Priorities with Jersey . Also, a SecurityContext will be passed between filters and also injected into your resource class.
As I said, I donโt think it is very elegant to create another filter, but it works for this purpose. Also, I am not very familiar with the Jersey test platform, as I am still starting with it, but there are many configuration options for deployment in the context of a servlet. I do not know if we can configure the necessary authentication mechanism for this case, but it can be interesting.
Edit: In the beginning, I explained how to set the field for the test object, but we can also pass the deceived object to the method. For example, we could mock ContainterRequestContext in the filter method and call filter ourselves by passing mocked ContainerRequestContext . But this is useful only when we actually test the filter class individually and create it ourselves, which is not the case here.