gpt4 book ai didi

java - 在对 Spring REST Controller 进行单元测试时注入(inject) @AuthenticationPrincipal

转载 作者:IT老高 更新时间:2023-10-28 13:54:00 25 4
gpt4 key购买 nike

我在尝试测试接收 UserDetails 作为使用 @AuthenticationPrincipal 注释的参数的 REST 端点时遇到问题。

似乎没有使用在测试场景中创建的用户实例,而是尝试使用默认构造函数进行实例化:org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.andrucz .app.AppUserDetails]: 未找到默认构造函数;

REST 端点:

@RestController
@RequestMapping("/api/items")
class ItemEndpoint {

@Autowired
private ItemService itemService;

@RequestMapping(path = "/{id}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
public Callable<ItemDto> getItemById(@PathVariable("id") String id, @AuthenticationPrincipal AppUserDetails userDetails) {
return () -> {
Item item = itemService.getItemById(id).orElseThrow(() -> new ResourceNotFoundException(id));
...
};
}
}

测试类:

public class ItemEndpointTests {

@InjectMocks
private ItemEndpoint itemEndpoint;

@Mock
private ItemService itemService;

private MockMvc mockMvc;

@Before
public void setup() {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(itemEndpoint)
.build();
}

@Test
public void findItem() throws Exception {
when(itemService.getItemById("1")).thenReturn(Optional.of(new Item()));

mockMvc.perform(get("/api/items/1").with(user(new AppUserDetails(new User()))))
.andExpect(status().isOk());
}

}

如何在不切换到 webAppContextSetup 的情况下解决该问题?我想编写完全控制服务模拟的测试,所以我使用 standaloneSetup.

最佳答案

这可以通过将 HandlerMethodArgumentResolver 注入(inject)到您的 Mock MVC 上下文或独立设置中来完成。假设您的 @AuthenticationPrincipalParticipantDetails 类型:

private HandlerMethodArgumentResolver putAuthenticationPrincipal = new HandlerMethodArgumentResolver() {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.getParameterType().isAssignableFrom(ParticipantDetails.class);
}

@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return new ParticipantDetails(…);
}
};

这个参数解析器可以处理类型 ParticipantDetails 并且只是凭空创建它,但是你会看到你得到了很多上下文。稍后,这个参数解析器被附加到模拟 MVC 对象:

@BeforeMethod
public void beforeMethod() {
mockMvc = MockMvcBuilders
.standaloneSetup(…)
.setCustomArgumentResolvers(putAuthenticationPrincipal)
.build();
}

这将导致您的 @AuthenticationPrincipal 带注释的方法参数填充来自解析器的详细信息。

关于java - 在对 Spring REST Controller 进行单元测试时注入(inject) @AuthenticationPrincipal,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38330597/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com