WebFlux api层测试返回404



我正在尝试用Spring Boot 3.0开始使用Spring WebFlux

我正在用一个开放的API生成器构建一个人API。应用程序运行并在手动测试时给出预期的结果。

但是我不能得到API层单元测试。

这是我的测试类

@WebFluxTest(controllers = {PersonApiController.class})
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {PersonMapperImpl.class, H2PersonRepository.class, PersonRepository.class})
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
class PersonRouterTest {
@MockBean
private PersonService personService;
@Autowired
private WebTestClient client;
@ParameterizedTest
@CsvSource({"1234, Max Mustermann", "5678, Erika Musterfrau"})
void retrieve_a_name(String id, String name) {
when(personService.getPersonDataByID(1234)).thenReturn(Mono.just(new PersonData(1234, "Max Mustermann")));
when(personService.getPersonDataByID(5678)).thenReturn(Mono.just(new PersonData(5678, "Erika Musterfrau")));
client.get()
.uri(uriBuilder -> uriBuilder
.path("/persons/{id}")
.build(id))
.accept(MediaType.ALL)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(MediaType.APPLICATION_JSON)
.expectBody()
.jsonPath("$.name").isEqualTo(name);
}

这是我的控制器类

@Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2022-12-
09T09:14:36.692713900+01:00[Europe/Vienna]")
@Controller
@RequestMapping("${openapi.openAPIDefinition.base-path:}")
public class PersonApiController implements PersonApi {
private final PersonApiDelegate delegate;
public PersonApiController(@Autowired(required = false) PersonApiDelegate delegate) {
this.delegate = Optional.ofNullable(delegate).orElse(new PersonApiDelegate() {});
}
@Override
public PersonApiDelegate getDelegate() {
return delegate;
}
}
API接口:
@Tag(
name = "Person",
description = "the Person API"
)
public interface PersonApi {
default PersonApiDelegate getDelegate() {
return new PersonApiDelegate() {
};
}
@Operation(
operationId = "findPersonById",
summary = "Find Person by ID",
tags = {"Person"},
responses = {@ApiResponse(
responseCode = "200",
description = "successful operation",
content = {@Content(
mediaType = "application/json",
schema = @Schema(
implementation = PersonData.class
)
)}
)}
)
@RequestMapping(
method = {RequestMethod.GET},
value = {"/persons/{id}"},
produces = {"application/json"}
)
default Mono<ResponseEntity<PersonData>> findPersonById(@Parameter(name = "id",description = "Person ID",required = true) @PathVariable("id") Integer id, @Parameter(hidden = true) final ServerWebExchange exchange) {
return this.getDelegate().findPersonById(id, exchange);
}
@Operation(
operationId = "savePerson",
summary = "Creates a new Person",
tags = {"Person"},
responses = {@ApiResponse(
responseCode = "200",
description = "successful operatoin",
content = {@Content(
mediaType = "application/json",
schema = @Schema(
implementation = PersonData.class
)
)}
)}
)
@RequestMapping(
method = {RequestMethod.POST},
value = {"/persons"},
produces = {"application/json"},
consumes = {"application/json"}
)
default Mono<ResponseEntity<PersonData>> savePerson(@Parameter(name = "PersonData",description = "") @RequestBody(required = false) Mono<PersonData> personData, @Parameter(hidden = true) final ServerWebExchange exchange) {
return this.getDelegate().savePerson(personData, exchange);
}
}

最后是委托impl:

@Service
public class PersonDelegateImpl implements PersonApiDelegate {
public static final Mono<ResponseEntity<?>> RESPONSE_ENTITY_MONO = Mono.just(ResponseEntity.notFound().build());
private final PersonService service;
private final PersonMapper mapper;
public PersonDelegateImpl(PersonService service, PersonMapper mapper) {
this.service = service;
this.mapper = mapper;
}
public static <T> Mono<ResponseEntity<T>> toResponseEntity(Mono<T> mono) {
return mono.flatMap(t -> Mono.just(ResponseEntity.ok(t)))
.onErrorResume(t -> Mono.just(ResponseEntity.internalServerError().build()));
}
@Override
public Mono<ResponseEntity<PersonData>> findPersonById(Integer id, ServerWebExchange exchange) {
Mono<com.ebcont.talenttoolbackend.person.PersonData> personDataByID = service.getPersonDataByID(id);
return toResponseEntity(personDataByID.map(mapper::map));
}
@Override
public Mono<ResponseEntity<PersonData>> savePerson(Mono<PersonData> personData, ServerWebExchange exchange) {
return PersonApiDelegate.super.savePerson(personData, exchange);

如果我运行测试类,我总是得到:

< 404 NOT_FOUND Not Found
< Content-Type: [application/json]
< Content-Length: [139]
{"timestamp":"2022-12-09T08:45:41.278+00:00","path":"/persons/1234","status":404,"error":"Not Found","message":null,"requestId":"4805b8b8"}

我试图改变上下文配置,但我没有让它工作。

我发现了问题,将测试配置更改为:

@WebFluxTest
@ExtendWith(SpringExtension.class)
@ContextConfiguration(classes = {PersonMapperImpl.class, H2PersonRepository.class, PersonRepository.class, PersonApiController.class, PersonDelegateImpl.class})
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)

解决了我的问题。无法识别控制器bean。我必须添加PersonApiCrontroller和PersonDelegateImpl到Context Config。然后我从@WebFluxTest注释中删除了PersonApiController。

最新更新