I have a REST POST endpoint which is used to create an entity. I've trying to test it with MockMVC but every time that i sent the request i received a 415 status code (media not supported): java.lang.AssertionError: Status expected:<201> but was:<415> Expected:201 Actual:415
The endpoint accepts json body in the request and I sent this data using the MockMVC contentType as APPLICATION_JSON_VALUE and the content method with the serialized object by Jackson.
The controller ALSO is managed my Spring Security Filters but i think this is not the problem as i'm using the @AutoConfigureMockMvc(addFilters = false)
and the HTTP status code is related to not supported media type and not about any security exception.
I've found a plenty of topics talking about it but none was able to solve my problem. One of the cases was including the @EnableWebMvc
into the Controller OR as a configuration bean test, but none work it.
My attempt with @EnableWebMvc as test bean
@TestConfiguration
@EnableWebMvc
public class ProdutoControllerConfigurationTest {
@Bean
public ProdutoController produtoController() {
return new ProdutoController(/* dependencies by autowired */);
}
}
EDIT: I also tried with different MediaType like MediaType.APPLICATION_JSON and MediaType.APPLICATION_JSON_VALUE
My DTO class
public class CriarProdutoDTO {
@NotNull
@Size(min = 2)
@JsonProperty("nome_produto")
private final String nomeProduto;
@DecimalMin("0.1")
private final BigDecimal preco;
private final String descricao;
@NotNull
@Min(0)
@JsonProperty("quantidade_estoque")
private final Integer quantidadeEstoque;
@NotNull
@Min(1)
@JsonProperty("categoria_id")
private final Integer categoriaId;
public CriarProdutoDTO(String nomeProduto, BigDecimal preco, String descricao, Integer quantidadeEstoque, Integer categoriaId) {
this.nomeProduto = nomeProduto;
this.preco = preco;
this.descricao = descricao;
this.quantidadeEstoque = quantidadeEstoque;
this.categoriaId = categoriaId;
}
}
My current tests:
@ActiveProfiles("testes")
@ExtendWith(SpringExtension.class)
@SpringBootTest
@WebAppConfiguration
@AutoConfigureMockMvc(addFilters = false)
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.ANY)
public class ProdutoControllerTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private ObjectMapper objectMapper;
@Test
public void deveRetornarCreated_criacaoProdutoSucesso() throws Exception {
CriarProdutoDTO criarProdutoDTO = new CriarProdutoDTO("Nome", new BigDecimal("2.0"), "DESCRIÇÃO", 2, 1);
mockMvc.perform(MockMvcRequestBuilders.post("/api/produtos")
.contentType(MediaType.APPLICATION_JSON_VALUE)
.content(objectMapper.writeValueAsString(criarProdutoDTO)))
.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isCreated());
}
}
My Controller:
@RestController
@RequestMapping(value = "/api/produtos")
public class ProdutoController {
@Autowired
private ProdutoService produtoService;
@Autowired
private CriarProdutoDtoToProdutoConverter produtoConverter;
@PostMapping
@ResponseStatus(HttpStatus.CREATED)
public void cadastrar(@RequestBody @Valid CriarProdutoDTO produtoDTO) {
Produto novoProduto = produtoConverter.converter(produtoDTO);
produtoService.cadastrar(novoProduto);
}
}
try add Accept header to your request
Accept=application/json
I found out the problem. The problem was occurring in Jackson's Serialization from my Data Transfer Object (DTO)
My DTO has an args-constructor and because of that i have to use the @JsonCreator
to point the args constructor. What i didn't expect was that you must annotate all the constructor parameters with @JsonProperty
as Jackson didn't know the exact order to instantiate the object from the construtor, that was my problem.
Another way is creating a bean for that, so you don't have to use the @JsonCreator
The solution:
@JsonCreator
public CriarProdutoDTO(
@JsonProperty("nome_produto") String nomeProduto, @JsonProperty("preco") BigDecimal preco,
@JsonProperty("descricao") String descricao, @JsonProperty("quantidade_estoque") Integer quantidadeEstoque,
@JsonProperty("categoria_id") Integer categoriaId) {
this.nomeProduto = nomeProduto;
this.preco = preco;
this.descricao = descricao;
this.quantidadeEstoque = quantidadeEstoque;
this.categoriaId = categoriaId;
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.