UnsupportedMediaTypeException: Content type 'application/octet-stream' not supported for bodyType=java.util.Map<java.lang.String, java.lang.String>))
Asked Answered
S

2

7

I am facing below error while running junit for controller. I have already set content-type as Json, still error is same. Any suggestion what could be the issue ?

Error is

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>))

Controller is

@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 class as below:

@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 is as below:

@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();
    }
}
Stoffel answered 31/3, 2021 at 6:27 Comment(0)
S
6

After debugging , i found that even response header need to be set with content-type as readWithMessageReaders () method of BodyExtractors class check for content-type.

.withHeader(CONTENT_TYPE, APPLICATION_JSON_VALUE)

set in below code fixed the failing testcase

@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();
    }
Stoffel answered 31/3, 2021 at 7:8 Comment(0)
G
1

In my case I fixed the issue parsing manually one of the parts that contains a json object

This code did not work

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

This one

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

does. My Spring boot version is 2.6.3 with java 17

Galicia answered 1/2, 2022 at 15:18 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.