Mocking SecurityContext in Jersey Tests
Jersey has a great possibility to write integration test for REST-APIs, written with Jersey. Just extend the class JerseyTest and go for it.
I ran in an issue, where I had to mock a SecurityContext, so that the SecurityContext includes a special UserPrincipal. The challenge is that Jersey wraps the SecurityContext in an own class SecurityContextInjectee in tests. So I have to add my SecurityContext Mock to this Jersey’s wrapper class. Let me demonstrate it in an example.
Let say I have the following Jersey Resource:
01 02 03 04 05 06 07 08 09 10 | @Path ( "hello/world" ) public class MyJerseyResource { @GET public Response helloWorld( @Context final SecurityContext context) { String name = context.getUserPrincipal().getName(); return Response.ok( "Hello " + name, MediaType.TEXT_PLAIN).build(); } } |
In my test, I have to mock the SecurityContext, so that a predefined user principal can be used during the tests. I use Mockito as mocking framework. My mock looks like the following one
1 2 3 4 5 6 7 | final SecurityContext securityContextMock = mock(SecurityContext. class ); when(securityContextMock.getUserPrincipal()).thenReturn( new Principal() { @Override public String getName() { return "Alice" ; } }); |
For adding this mocked SecurityContext to the wrapper class SecurityContextInjectee, I have to configure a ResourceConfig with a modified ContainerRequestContext in my Jersey Test. The mocked SecurityContext can be set in this modified ContainerRequestContext and then it will be used in the wrapper class:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | @Override public Application configure() { final SecurityContext securityContextMock = mock(SecurityContext. class ); when(securityContextMock.getUserPrincipal()).thenReturn( new Principal() { @Override public String getName() { return "Alice" ; } }); ResourceConfig config = new ResourceConfig(); config.register( new ContainerRequestFilter(){ @Override public void filter( final ContainerRequestContext containerRequestContext) throws IOException { containerRequestContext.setSecurityContext(securityContextMock); } }); return config; } |
Then, the whole test for my resource looks like the following one:
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | public class MyJerseyResourceTest extends JerseyTest { @Test public void helloWorld() throws Exception { Response response = target( "hello/world" ).request().get(); assertThat(response.getStatus()).isEqualTo(HttpStatus.SC_OK); assertThat(response.getEntity()),isEqualTo( "Hello Alice" ); } @Override public Application configure() { final SecurityContext securityContextMock = mock(SecurityContext. class ); when(securityContextMock.getUserPrincipal()).thenReturn( new Principal() { @Override public String getName() { return "Alice" ; } }); ResourceConfig config = new ResourceConfig(); config.register( new ContainerRequestFilter(){ @Override public void filter( final ContainerRequestContext containerRequestContext) throws IOException { containerRequestContext.setSecurityContext(securityContextMock); } }); return config; } |
Do you have a smarter solution for this problem? Let me know it and write a comment below.
Published on Java Code Geeks with permission by Sandra Parsick, partner at our JCG program. See the original article here: Mocking SecurityContext in Jersey Tests Opinions expressed by Java Code Geeks contributors are their own. |
A good article that could be a little bitter with the appropriate Maven/Gradle dependencies and imports for the Java classes involved.