I want to write some kind of unit test which depends on Spring Security.
For example, I have some service method which uses some repository and marked with @PreAuthorize annotation. Repository I can mock with Mockito, there is no problem. Also I can mock Security Context by @WithSecurityContext annotation. But when I run test, the @PreAuthorize annotation is just ignored. Of course I can run that test with @SpringBootTest annotation as an integration test and in this case the Security Context is up but this way is heavy and slow.
Is there a way to run unit test with only Spring Security Context raised?
UPDATE
Made an example of such kind of test. Thanks to @Sam Brannen for giving right direction.
@ActiveProfiles("method-security-test")
@RunWith(SpringRunner.class)
@SpringBootTest(classes = {ExampleService.class, ExampleServiceTest.MethodSecurityConfiguration.class})
public class ExampleServiceTest {
private ExampleService service;
@Autowired
public void setService(ExampleService service) {
this.service = service;
}
@Test
@WithMockUser(username = "john_doe")
public void testAuthenticated() {
String actualMessage = service.example();
Assert.assertEquals("Message of john_doe", actualMessage);
}
@Test(expected = AuthenticationException.class)
public void testNotAuthenticated() {
service.example();
Assert.fail();
}
@TestConfiguration
@EnableGlobalMethodSecurity(prePostEnabled = true)
static class MethodSecurityConfiguration extends GlobalMethodSecurityConfiguration {
}
}
@Service
class ExampleService {
@PreAuthorize("isAuthenticated()")
String example() {
Principal principal = SecurityContextHolder.getContext().getAuthentication();
return "Message of " + principal.getName();
}