es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

@CurrentSecurityContext siempre inyecta null en las pruebas de integración de mockMvc?

Estoy utilizando la anotación de seguridad de Spring, @CurrentSecurityContext, para inyectar el objeto de autenticación. Esto funciona correctamente cuando la aplicación se está ejecutando, pero en un @SpringBootTest siempre inyecta null, incluso cuando se utiliza @WithMockUser.

Cuando agrego puntos de interrupción, el objeto de autenticación en el contexto de SpringSecurityContext se rellena correctamente con un usuario principal falso, pero el resolvedor @CurrentSecurityContext, es decir, CurrentSecurityContextArgumentResolver, nunca se utiliza, no se detendrá en ningún punto de interrupción (constructor o método de resolución) en esta clase.

Estoy utilizando Spring Boot:

<groupid>org.springframework.boot</groupid>
<artifactid>spring-boot-starter-parent</artifactid>
<version>2.2.6.RELEASE</version>

Y uso mockMvc para realizar una prueba:

@Test
@WithMockUser
void activate_NotActivatedYet() {
  ....
  var result = mockMvc.perform(put(url).contentType(MediaType.APPLICATION_JSON)
        .content(content)
        .characterEncoding(CHAR_ENCODING))
    .andDo(print())
    .andDo(result -> flushIfNeeded())
    .andDo(result -> entityManager.clear());
 .....
}

Y mi endpoint REST:

@PutMapping("/{code}/activate")
public ResponseEntity<promocoderestdto> activate(@CurrentSecurityContext Authentication authentication,
                                                 @PathVariable String code) {
    log.info("Solicitando activar el código promocional con código [{}]", code);
Tags:  , , , ,

Answer

  1. Avatar for davy.ai

    El problema aquí es que @WithMockUser no está inyectando correctamente el objeto de autenticación en la prueba. Una solución alternativa es crear manualmente el objeto de autenticación y establecerlo usando SecurityContextHolder durante la configuración:

    @BeforeEach
    public void setUp() {
        Authentication authentication = new UsernamePasswordAuthenticationToken(
                "user", "password", Collections.singletonList(new SimpleGrantedAuthority("ROLE_USER")));
        SecurityContextHolder.getContext().setAuthentication(authentication);
    }
    

    Alternativamente, puedes intentar usar @AutoConfigureMockMvc en lugar de @SpringBootTest. Esto configurará automáticamente la instancia mockMvc para las pruebas e inyectará correctamente el objeto de autenticación usando @WithMockUser:

    @ExtendWith(SpringExtension.class)
    @AutoConfigureMockMvc
    @WebMvcTest(MyController.class)
    public class MyControllerTest {
    
        @Autowired
        private MockMvc mockMvc;
    
        @Test
        @WithMockUser
        void activate_NotActivatedYet() {
          ....
          var result = mockMvc.perform(put(url).contentType(MediaType.APPLICATION_JSON)
                .content(content)
                .characterEncoding(CHAR_ENCODING))
            .andDo(print())
            .andDo(result -> flushIfNeeded())
            .andDo(result -> entityManager.clear());
         .....
        }
    
    }
    

    Con esta configuración, @WithMockUser debería inyectar correctamente el objeto de autenticación en la prueba.

Comments are closed.