Mocking Spring Security Context for Unit Testing

Today, while writing unit test case for one of the Java method which looks like below:

public ApplicationUser getApplicationUser() {
	ApplicationUser applicationUser = (ApplicationUser) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
	return applicationUser;
}

I want to mock Spring Security Context to get the Principal, to achieve the same I mocked each level of method calls as follows:

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.mock;
import org.mockito.MockitoAnnotations;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import com.arpit.security.user.ApplicationUser;

public class BaseTest {

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

	@Test
	public void mockApplicationUser() {
		ApplicationUser applicationUser = mock(ApplicationUser.class);
		Authentication authentication = mock(Authentication.class);
		SecurityContext securityContext = mock(SecurityContext.class);
		when(securityContext.getAuthentication()).thenReturn(authentication);
		SecurityContextHolder.setContext(securityContext);
		when(SecurityContextHolder.getContext().getAuthentication().getPrincipal()).thenReturn(applicationUser);
	}

}

Expected Exception Rule and Mocking Static Methods – JUnit

Today I was asked to consume a RESTful service so I started implementing it following Robert Cecil Martin’s rules for TDD and came across a new way (atleast for me) of testing the expected exception along with the error message so thought of sharing the way I implemented it as part of this post.

To start with let’s write a @Test and specify rule that our code will throw a specific exception for our example it’s EmployeeServiceException which we will verify it using ExpectedException which will provide us more precise information about the exception expected to be thrown with the ability to verify error message, as follows:


@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassWithStaticMethod.class)
public class EmployeeServiceImplTest {

	@InjectMocks
	private EmployeeServiceImpl employeeServiceImpl;

	@Rule
	public ExpectedException expectedException = ExpectedException.none();

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

	@Test
	public void addEmployeeForNull() throws EmployeeServiceException {
		expectedException.expect(EmployeeServiceException.class);
		expectedException.expectMessage("Invalid Request");
		employeeServiceImpl.addEmployee(null);
	}

}

Now we will create an implementing class for our @Test which will throw EmployeeServiceException whenever the request is null, for me it’s EmployeeServiceImpl as follows:

EmployeeServiceImpl.java


public class EmployeeServiceImpl implements IEmployeeService {

	@Override
	public String addEmployee(final Request request)
			throws EmployeeServiceException {
		if (request == null) {
			throw new EmployeeServiceException("Invalid Request");
		}
		return null;
	}
}

Next we will write a @Test where we will mock static method which accepts input parameters with return type using PowerMockito.mockStatic(), verify it using PowerMockito.verifyStatic() and finally do an Assert to record test pass or failure status, as follows:


@Test
	public void addEmployee() throws EmployeeServiceException {
		PowerMockito.mockStatic(ClassWithStaticMethod.class);
		PowerMockito.when(ClassWithStaticMethod.getDetails(anyString()))
				.thenAnswer(new Answer<String>() {
					@Override
					public String answer(InvocationOnMock invocation)
							throws Throwable {
						Object[] args = invocation.getArguments();
						return (String) args[0];
					}
				});
		final String response = employeeServiceImpl.addEmployee(new Request(
				"Arpit"));
		PowerMockito.verifyStatic();
		assertThat(response, is("Arpit"));
	}

Now we will provide the implementation for our @Test inside EmployeeServiceImpl itself. To do that, lets modify the EmployeeServiceImpl to have static method call as part of else statement of addEmployee, as follows:


public class EmployeeServiceImpl implements IEmployeeService {

	@Override
	public String addEmployee(final Request request)
			throws EmployeeServiceException {
		if (request == null) {
			throw new EmployeeServiceException("Invalid Request");
		} else {
			return ClassWithStaticMethod.getDetails(request.getName());
		}
	}
}

Where getDetails is a static method inside ClassWithStaticMethod:


public class ClassWithStaticMethod {

	public static String getDetails(String name) {
		return name;
	}
}


 
Complete source code is hosted on github.