How to add a header to a MockMvc request, depending on test annotation?

ch4mp picture ch4mp · Jan 31, 2018 · Viewed 8.3k times · Source

As a follow up to this question, I wonder how to transparently add an "Authorization" header to a MockHttpServletRequestBuilder, only if a given annotation is present on the test.

sample:

@RunWith(SpringRunner.class)
@EnableSpringDataWebSupport
@WebMvcTest(MyController.class)
@Import({WebSecurityConfig.class})
public class MyControllerTest {

    @Autowired
    protected MockMvc mockMvc;

    @Test
    @WithJwt(principal = "admin", authorities = {"READ_USERS"})
    public void readUsersAuthorityCanListUsers() throws Exception {
        final List<User> users = Arrays.asList(admin, user);
        when(userRepo.findAll(any(Pageable.class))).thenReturn(new PageImpl<>(users));

        this.mockMvc
                .perform(get("/")
                        .header("Authorization", "Bearer foo"))
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.content", hasSize(users.size())));
    }
}

How to post-process the request builder to automatically apply .header("Authorization", "Bearer foo") if the test is decorated with @WithJwt?

Answer

ch4mp picture ch4mp · Feb 18, 2019

I ended to wrap MockMvc and proxy method calls, adding the Authorization header.

This would be over-kill for a single header, but this MockMvcHelper also sets content-type and accept headers, provides shortcuts to issue simple api calls (get, post, put patch, delete with default headers and serialization), etc.

You can have a look at this wrapper at the end of the solution to other question: https://stackoverflow.com/a/48540159/619830