2

I'm using spring boot and I want to assert an asynchronous side effect by calling a secured endpoint with MockMvc.

I have been using Awaitility, but apparently the mocked security context is lost when executing in a different thread.

I couldn't find a way of passing the context, I tried with SecurityContextHolder.setContext() but it didn't work, I guess spring's MockMvc stores the context in a different way.

  @Test
  @WithMockUser(authorities = "admin", username = "user")
  void shouldRunSideEffectAsync() throws Exception {
    mockMvc.perform(post("/foo")).andExpect(status().isAccepted());
    await()
        .atMost(TIMEOUT)
        .untilAsserted(() -> mockMvc.perform(get("/foo")).andExpect(status().isOk()));
  }

The GET would return 404 for a while and then 200 when the async task is completed. However this will always return 403 as the MockUser info is lost.

How can I solve this?

jcfandino
  • 320
  • 5
  • 12

1 Answers1

2

You almost got it. Security for MockMvc is implemented by TestSecurityContextHolderPostProcessor, which uses the TestSecurityContextHolder to set/get the security context. That is just a wrapper around the SecurityContextHolder.

So you can use TestSecurityContextHolder.setContext() in the awaitility thread and it should work.

jhyot
  • 3,733
  • 1
  • 27
  • 44