22

I'm wondering how I should go about authenticating a user for my tests? As it stands now all tests I will write will fail because the endpoints require authorization.

Test code:

@RunWith(SpringRunner.class)
@WebMvcTest(value = PostController.class)
public class PostControllerTest {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private PostService postService;

    @Test
    public void testHome() throws Exception {
        this.mvc.perform(get("/")).andExpect(status().isOk()).andExpect(view().name("posts"));
    }


}

One solution I found is to disable it by setting secure to false in @WebMvcTest. But that's not what I'm trying to do.

Any ideas?

Lithicas
  • 3,793
  • 7
  • 23
  • 32

2 Answers2

54

Spring Security provides a @WithMockUser annotation that can be used to indicate that a test should be run as a particular user:

@Test
@WithMockUser(username = "test", password = "test", roles = "USER")
public void withMockUser() throws Exception {
    this.mockMvc.perform(get("/")).andExpect(status().isOk());
}

Alternatively, if you're using basic authentication, you could send the required Authorization header:

@Test
public void basicAuth() throws Exception {
    this.mockMvc
            .perform(get("/").header(HttpHeaders.AUTHORIZATION,
                    "Basic " + Base64Utils.encodeToString("user:secret".getBytes())))
            .andExpect(status().isOk());
}
Andy Wilkinson
  • 108,729
  • 24
  • 257
  • 242
  • 7
    Spring Security even has built-in support for [Testing HTTP Basic Authentication](http://docs.spring.io/spring-security/site/docs/current/reference/htmlsingle/#testing-http-basic-authentication). ;) – Sam Brannen Jun 14 '16 at 20:24
  • 1
    I've seen this example but I don't have access to the annotation for some reason. Am I missing to include something? – Lithicas Jun 14 '16 at 20:59
  • 16
    The annotation is included in _spring-security-test_. Just add the dependency _org.springframework.security:spring-security-test_ to your project – Cèsar Jun 15 '16 at 11:19
  • What if you use a jwt token? – Yannick Mussche Feb 23 '23 at 16:13
10

As an alternative to the previous answer, it's possible to use the following:

@Test
public void basicAuth() throws Exception {
    this.mockMvc
            .perform(get("/")
                .with(SecurityMockMvcRequestPostProcessors.httpBasic("user", "secret"))
            )
            .andExpect(status().isOk());
}

since it will generate the same header:

Headers = [Content-Type:"...", Authorization:"Basic dXNlcjpzZWNyZXQ="]
PavelPraulov
  • 589
  • 6
  • 18