Mockito 为拦截器模拟 HttpServletRequest

Mockito mock HttpServletRequest for interceptor

我必须检查是否调用了某些拦截器逻辑。 拦截器通过 request.getUserPrincipal 获取用户主体。所以我模拟了 HttpServletRequest 以提供一些自定义逻辑。 但是 request.getUserPrincipal 始终为 null,因为应用的不是我模拟的 servletRequest,而是 mockMvc 生成的数据

@WebMvcTest(value = MyApi.class)
public class UserDetailsInterceptorTest {
    private static final String USER = "User";
    private static final String ROLE = "Manager";

    @Autowired
    private MockMvc mockMvc;

    @Mock
    private HttpServletRequest request;

    private final String rootUrl = "/v1/my/info";
    
    @Test
    void interceptPositive() throws Exception {
        Principal principal = () -> USER;
        KeycloakAccount account = new SimpleKeycloakAccount(principal, Collections.singleton(ROLE), null);
        when(request.getUserPrincipal()).thenReturn(new KeycloakAuthenticationToken(account,false));
        mockMvc.perform(get(rootUrl)
                .contentType(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk());
        //check interceptors        
    }
}

@Component
public class UserDetailsInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(
            HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        AccessToken token = null;
        String tokenString  = null;
        Principal principal = request.getUserPrincipal(); //null despite beeing mocked
        //other code    
    }
}

模拟 HttpServletRequest 或使用 Mockito 提供主体的正确方法是什么?

我发现 mockMvc 实际上允许直接传递主体

mockMvc.perform(get(rootUrl)
        .principal(principal) //this way
        .contentType(MediaType.APPLICATION_JSON))
        .andExpect(status().isOk());

不需要模拟 HttpServletRequest