I have a library-module written using Spring Boot 1.5.21.
The library has a @Service
with some methods annotated with @PreAutorize
allowing only users with ADMIN authority to perform some actions, for example a delete.
Then I have a Spring Boot Application that uses that library. If I run the app and manually test it, it works. Only ADMINs can delete. I'd like to write test for it.
I was thinking in writing separate test for module and for the main app. In my module I can successfully unit test the operations. But I'm having troubles testing the @PreAuthotize
, because the security context does not exist in the module, but in the main app. Is there a way to test that annotation in the module, and not in the main app?
The relevant code of my library:
@Service
public class MyService {
@PreAuthorize("hasAuthority('ADMIN')")
public void delete (long id){
.....
}
}
@RunWith(SpringRunner.class)
public class MyServiceTest {
private MyService service;
@Test
@WithAnonymousUser
public void deleteShouldFailIfAnonymous() {
... Verify exception thrown
}
@Test
@WithMockUser(authorities = 'USER')
public void deleteShouldFailIfNotAdmin() {
... Verify exception thrown
}
@Test
@WithMockUser(authorities = 'ADMIN')
public void deleteShouldPass() {
... Should pass
}
}
I've trying adding @EnableGlobalMethodSecurity(prePostEnabled = true)
but with no luck. And as said, the SecurityConfiguration is loaded in the main app, it does not exist in the library-module.
Can I test the @PreAuthorize
in the module or should I move it to the main app? I'd like to have it i the module if possible. Or maybe I can create a Context only for testing, but don't know how to do it.
Aspect-oriented features like @PreAuthorize
are implemented as advice. Usually, this means that Spring will create a decorator interface that intercepts the method call, performs the advice (in this case, checking the condition and throwing an exception if it fails), and then sends the call on to the service object.
When you use new MyService
, you're creating a bare object without the wrappers that implement the advice, so you won't see security, validation, caching, etc., applied. To see the behavior you want, you need to make your test bean @Autowired
using the Spring test support.