SKM IT World

Just another blog about IT

Mocking SecurityContext in Jersey Tests

Leave a comment


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:


@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

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:

@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:

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.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.