Paddy3108
Paddy3108

Reputation: 33

JUnit Test with Spring Security

I want to test, that I am not authorized to do that. Here my code:

/* imports */

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@WebAppConfiguration
public class AuthenticationTest {

private UsernamePasswordAuthenticationToken authentication;

@Autowired
private AuthenticationManager authManager;

    public void before() throws Exception {
        this.authentication = new UsernamePasswordAuthenticationToken("username", "password");
        SecurityContextHolder.getContext().setAuthentication(manager.authenticate(authentication));

    }

    @Test(expected = AccessDeniedException.class)
    public void postExperience() throws Exception {
        ExperienceEntity experience = new ExperienceEntity();
        experience.setExperience("Test");
        experience.setExperienceEng("Test");

        mockMvc.perform(
                    post(URL_EXPERIENCES).principal(authentication).content(json(experience)).contentType(CONTENT_TYPE))
                    .andExpect(status().isForbidden());
        }

Error Log:

org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.springframework.security.access.AccessDeniedException: Access is denied

I don't understand why this test don't work. I get these error, which I expected.

Upvotes: 2

Views: 3242

Answers (2)

Leonid Dashko
Leonid Dashko

Reputation: 4136

You can use expectCause to catch NestedServletException:

import org.junit.Rule;
import org.junit.rules.ExpectedException;

public class AuthenticationIntegrationTest {

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

    @Test
    public void postExperience() throws Exception {
        // given
        ...

        // then
        thrown.expectCause(is(instanceOf(AccessDeniedException.class)));

        // or thrown.expectCause(isA(AccessDeniedException.class));

        // when
        mockMvc.perform(post(URL_EXPERIENCES).principal(authentication).content(json(experience))
                .contentType(CONTENT_TYPE))
                .andExpect(status().isForbidden());
    }
}

Upvotes: 0

Sergey Prokofiev
Sergey Prokofiev

Reputation: 1885

It looks like the problem with exception type. You're expecting AccessDeniedException, but getting it wrapped in NestedServletException. To let your test be successful you can do it like so:

try {
    mockMvc.perform(post(URL_EXPERIENCES).principal(authentication)
        .content(json(experience)).contentType(CONTENT_TYPE))
        .andExpect(status().isForbidden());
    Assert.fail();
} catch (Exception e) {
    Assert.assertTrue(e.getCause() instanceof AccessDeniedException);
}

And remove expected property from your @Test annotation. Hope it helps!

Upvotes: 3

Related Questions