Inject @AuthenticationPrincipal beim Testen eines Spring REST-Controllers

Ich habe Probleme beim Testen eines Ruheendpunkts, der ein @ empfängUserDetails als mit @ kommentierter Paramet@AuthenticationPrincipal.

Scheint, als ob die im Testszenario erstellte Benutzerinstanz nicht verwendet wird. Stattdessen wird versucht, mithilfe des Standardkonstruktors eine Instanz zu erstellen:org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.andrucz.app.AppUserDetails]: No default constructor found;

REST-Endpunkt:

@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));
            ...
        };
    }
}

Testklasse:

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());
    }

}

Wie kann ich das Problem lösen, ohne zu @ wechseln zu müssewebAppContextSetup? Ich möchte Tests schreiben, die die vollständige Kontrolle über Service-Mocks haben, also benutze ichstandaloneSetup.

Antworten auf die Frage(8)

Ihre Antwort auf die Frage