0

I am trying to create unit tests for the following class:

@Secured
@Provider
@Priority(Priorities.AUTHORIZATION)
public class AuthorizationFilter implements ContainerRequestFilter {

    @Context
    private ResourceInfo resourceInfo;

    @Context 
    private SecurityContext securityContext;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {

        // Get the resource class which matches with the requested URL
        // Extract the permissions declared by it
        Class<?> resourceClass = resourceInfo.getResourceClass();
        List<Permission> classPermissions = extractPermissions(resourceClass);

        // Get the resource method which matches with the requested URL
        // Extract the permissions declared by it
        Method resourceMethod = resourceInfo.getResourceMethod();
        List<Permission> methodPermissions = extractPermissions(resourceMethod);

        try {
            String email = securityContext.getUserPrincipal().getName();

            // Check if the user is allowed to execute the method
            // The method annotations override the class annotations
            if (methodPermissions.isEmpty()) {
                checkPermissions(email, classPermissions);
            } else {
                checkPermissions(email, methodPermissions);
            }

        } catch (NotAuthorizedException e) {
            requestContext.abortWith(
                Response.status(Response.Status.FORBIDDEN).build());
        }
    }

    // Extract the permissions from the annotated element
    private List<Permission> extractPermissions(AnnotatedElement annotatedElement) {
        // get permissions
        return permissions;
    }

    protected void checkPermissions(String email, List<Permission> allowedPermissions) throws NotAuthorizedException {
        Permissions permissions = DBUserUtils.getUserPermissions(email);
        for (Permission permission : allowedPermissions){
            if (!permissions.hasPermission(permission))
                throw new NotAuthorizedException("Authorization header must be provided");;
        }
    }
}

With my current test class being:

@RunWith(MockitoJUnitRunner.class)
public class AuthorizationFilterTest {

    @Mock
    private ResourceInfo resourceInfo = mock(ResourceInfo.class);

    @Mock
    private SecurityContext securityContext = mock(SecurityContext.class);

    @Mock
    private static DBUserUtils dbUserUtils = mock(DBUserUtils.class);

    @InjectMocks
    private AuthorizationFilter authorizationFilter = spy(AuthorizationFilter.class);

    private ContainerRequestContext requestContext = mock(ContainerRequestContext.class);

    @Before 
    public void initMocks() {
        MockitoAnnotations.initMocks(this);

        doReturn(Endpoints.class).when(resourceInfo).getResourceClass();

        when(securityContext.getUserPrincipal()).thenReturn(new UserPrincipal() {
            @Override
            public String getName() {
                return "email";
            }
        });
    }


    @Test
    public void authorizationFilterAuthorizedTest() throws NotAuthorizedException, IOException{
        doReturn(getMethodByName(Endpoints.class, "createUser")).when(resourceInfo).getResourceMethod();
        authorizationFilter.filter(requestContext);
        verify(requestContext, times(0)).abortWith(any());
    }

    private Method getMethodByName(Class<?> classToUse, String methodName){
        Method[] methods = classToUse.getMethods();
        for (Method method : methods){
            if (method.getName().equals(methodName))
                return method;
        }
        return null;
    }
}

I am able to mock the private fields of the class, I can't seem to find a way to mock the static method DBUserUtils.getUserPermissions(email). Is this possible or am I just wasting my time?

I am using Mockito 1.10.19 and JUnit 4 for my tests.

I am new to mocking objects for unit tests so if I am going massively wrong somewhere, please let me know!

Thanks.

rj93
  • 523
  • 8
  • 25
  • 3
    You need some heavier tools for mocking static methods, e.g. PowerMock. – Mick Mnemonic Jul 19 '16 at 18:48
  • @MickMnemonic can you provide an example of how I would do this with PowerMock? – rj93 Jul 19 '16 at 18:52
  • In addition to what @MickMnemonic said: [Mockito limitations](https://github.com/mockito/mockito/wiki/FAQ#what-are-the-limitations-of-mockito). Also for powermock samples you can chek out [their wiki](https://github.com/jayway/powermock/wiki/MockitoUsage) – Morfic Jul 19 '16 at 18:52
  • @rj93, did you already have a look at [Mocking static methods with Mockito](http://stackoverflow.com/questions/21105403/mocking-static-methods-with-mockito)? – Mick Mnemonic Jul 19 '16 at 18:56
  • Thanks, I'll check them out now – rj93 Jul 19 '16 at 19:01

1 Answers1

1

To mock DBUserUtils.getUserPermissions(email) in your example, you can either a) use some additional frameworks (eg. PowerMock, as mentioned in comments to your question), or b) extract call to DBUserUtils.getUserPermissions(email) to a separate method:

Permissions getUserPermissions(String email) {
    return DBUserUtils.getUserPermissions(email);
}

which you can then mock in your tests:

doReturn(...).when(authorizationFilter).getUserPermissions(any());
korolar
  • 1,340
  • 1
  • 11
  • 20