1

在为控制器运行 junit 时,我面临以下错误。我已经将 content-type 设置为 Json,但错误仍然相同。任何建议可能是什么问题?

错误是

java.lang.AssertionError: expectation "expectNext({response=employee saved Successfully})" failed (expected: onNext({response=employee saved Successfully}); actual: onError(org.springframework.web.reactive.function.UnsupportedMediaTypeException: Content type 'application/octet-stream' not supported for bodyType=java.util.Map<java.lang.String, java.lang.String>))

控制器是

@Slf4j
@Controller
@RequiredArgsConstructor
public class EmployeeController {

    private final EmployeeService employeeService;
    
    @PostMapping(path ="/employees",produces =  APPLICATION_JSON_VALUE)
    public @ResponseBody Mono<Map<String, String>> saveEmployees(@RequestBody List<EmployeeDto> employeeDtos) {
        log.info("Received request to save employees [{}]", employeeDtos);
        return employeeService.saveEmployee(employeeDtos);
    }
}

服务等级如下:

@Service
@Slf4j
@RequiredArgsConstructor
public class EmployeeService {

    private final WebClient webClient;

    public Mono<Map<String, String>> saveEmployees(List<EmployeeDto> employeeDtos) {
        return webClient
                .post()
                .uri("/create-employees")
                .contentType(APPLICATION_JSON)
                .bodyValue(employeeDtos)
                .retrieve()
                .bodyToMono(new ParameterizedTypeReference<Map<String, String>>() {
                })
                .doOnError(e -> log.error("Failed to save employees {}: {}", employeeDtos, e));

Junit如下:

@Slf4j
@SpringBootTest
class EmployeeServiceTest {

private static final WireMockServer wireMockServer = new WireMockServer(wireMockConfig().dynamicPort());

    @Autowired
    private ObjectMapper objectMapper;

    @Autowired
    private EmployeeService employeeService;

    @Test
    void shouldMakeAPostApiCallToSaveEmployee() throws JsonProcessingException {
        var actualemployeeDtos = "....";
        var randomEmployeeDto = ...;
        wireMockServer.stubFor(post("/create-employees")
                .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON_VALUE))
                .withHeader(ACCEPT, containing(APPLICATION_JSON_VALUE))
                .withRequestBody(equalToJson(actualemployeeDtos))
                .willReturn(aResponse()
                        .withStatus(OK.value())
                        .withBody("{\"response\": \"employee saved Successfully\"}")));

        StepVerifier
                .create(employeeService.saveEmployee(List.of(randomEmployeeDto)))
                .expectNext(singletonMap("response", "employee saved Successfully"))
                .verifyComplete();
    }
}
4

2 回答 2

1

经过调试,我发现即使响应头也需要设置内容类型,因为 BodyExtractors 类的 readWithMessageReaders() 方法检查内容类型。

.withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)

在下面的代码中设置修复了失败的测试用例

@Test
    void shouldMakeAPostApiCallToSaveEmployee() throws JsonProcessingException {
        var actualemployeeDtos = "....";
        var randomEmployeeDto = ...;
        wireMockServer.stubFor(post("/create-employees")
                .withHeader(CONTENT_TYPE, equalTo(APPLICATION_JSON_VALUE))
                .withHeader(ACCEPT, containing(APPLICATION_JSON_VALUE))
                .withRequestBody(equalToJson(actualemployeeDtos))
                .willReturn(aResponse()
                        .withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)
                        .withStatus(OK.value())
                        .withBody("{\"response\": \"Employees saved Successfully\"}")));

        StepVerifier
                .create(employeeService.saveEmployee(List.of(randomEmployeeDto)))
                .expectNext(singletonMap("response", "Employees saved Successfully"))
                .verifyComplete();
    }
于 2021-03-31T07:08:21.423 回答
0

在我的情况下,我修复了手动解析包含 json 对象的部分之一的问题

此代码不起作用

@PostMapping(value = "salvaDomanda")
@ResponseBody
@ResponseStatus(HttpStatus.CREATED)
Domanda salvaDomanda(@RequestPart("data")  Domanda domanda,
                  @RequestPart(name = "files", required = false) MultipartFile[] files)

这个

@PostMapping(value = "salvaDomanda")
@ResponseBody
@ResponseStatus(HttpStatus.CREATED)
Domanda salvaDomanda(@RequestPart("data") String jsonDomanda,
                     @RequestPart(name = "files", required = false) MultipartFile[] files)
        throws ApplicationException, IOException {
    ObjectMapper mapper = new ObjectMapper();
    Domanda domanda = mapper.readValue(jsonDomanda, Domanda.class);

做。我的 Spring Boot 版本是 2.6.3,带有 java 17

于 2022-02-01T15:18:21.247 回答