Search code examples
javaspringspring-bootjunitspring-security

Test service method that has @PreAuthorize with JUnit


In Spring Boot 1.4.1, I want to do unit testing (not integration testing) on a service method that has restricted access with @PreAuthorize.

The problem is the @PreAuthorize doesn't seem to be checked when launching the test solo from Eclipse (haven't try with mvn test yet).

Then, if I miraculously manage to run the test correctly, I will try to work with the StudyService interface, not the impl.

Here is my test class :

@RunWith(MockitoJUnitRunner.class)
public class TestMethodSecurity {

    private static final Long STUDY_ID = 1L;

    @Mock
    private StudyRepository studyRepository;

    @InjectMocks
    private StudyServiceImpl studyService;


    @Before
    public void setup() {
        given(studyRepository.findOne(STUDY_ID)).willReturn(ModelsUtil.createStudy());
    }


    @Test
    public void findByIdWithoutAccessRightTest() {
        Study study = studyService.findById(STUDY_ID);
    }
}

This is the service :

@Service
public class StudyServiceImpl implements StudyService {


    @Autowired
    private StudyRepository studyRepository;


    @Override
    @PreAuthorize("hasAnyRole('DOES NOT EVENT CHECK SYNTAX")
    public Study findById(final Long id) {
        return studyRepository.findOne(id);
    }

}

The test succeed, which is a fail.


Solution

  • That's how I make it work :

    @RunWith(SpringRunner.class)
    @SpringBootTest
    @EnableGlobalMethodSecurity(prePostEnabled = true)
    @ActiveProfiles("test")
    public class StudySecurityTest {
    
        @Autowired
        private StudyService service;
    
        @MockBean
        private StudyRepository repository;
    
        @Test
        @WithAnonymousUser
        public void testAsAnonymous() {
            ...
        }
    
        @Test
        @WithMockKeycloakUser(id = LOGGED_USER_ID, username = LOGGED_USER_USERNAME, authorities = { "ROLE_USER" })
        public void testAsUser() {
            ...
        }
    }
    

    If you are interrested in @WithMockKeycloakUser, ask me.