Solucionado (ver solução)
Solucionado
(ver solução)
10
respostas

Teste retorna 500 e não 201

Ao fazer o teste do método POST, está retornando o erro 500, ao invés de retornar o código 201, como esperado. Segue o código que estou fazendo o teste e a stacktrace:

@Test
    @DisplayName("Deveria devolver código http 201, quando as informações estiverem válidas")
    @WithMockUser
    void createBeneficiaryCenario2() throws Exception {
        DadosCadastroBeneficiario dadosCadastroBeneficiario = new DadosCadastroBeneficiario(
                "Nome",
                "1165459787",
                LocalDate.parse("2002-03-12"),
                LocalDate.parse("2023-10-25"),
                LocalDate.parse("2023-10-25"),
                dadosCadastroDocumento(),
                dadosEndereco());

        when(beneficiarioRepository.save(any())).thenReturn(new Beneficiario(dadosCadastroBeneficiario));

        var response = mvc
                .perform(
                        post("/beneficiaries")
                                .contentType(MediaType.APPLICATION_JSON)
                                .content(dadosCadastroBeneficiarioJson.write(dadosCadastroBeneficiario).getJson()
                                )
                )
                .andReturn().getResponse();

        DadosDetalhamentoBeneficiario dadosDetalhamentoBeneficiario = new DadosDetalhamentoBeneficiario(
                null,
                dadosCadastroBeneficiario.nome(),
                dadosCadastroBeneficiario.telefone(),
                dadosCadastroBeneficiario.dataNascimento(),
                dadosCadastroBeneficiario.dataInclusao(),
                dadosCadastroBeneficiario.dataAtualizacao(),
                null,
                null);

        assertThat(response.getStatus()).isEqualTo(HttpStatus.CREATED.value());

        String jsonEsperado = dadosDetalhamentoBeneficiarioJson.write(dadosDetalhamentoBeneficiario).getJson();

        assertThat(response.getContentAsString()).isEqualTo(jsonEsperado);
    }
10 respostas

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /beneficiaries
       Parameters = {}
          Headers = [Content-Type:"application/json;charset=UTF-8", Content-Length:"469"]
             Body = {"nome":"Nome","telefone":"1165459787","dataNascimento":"2002-03-12","dataInclusao":"2023-10-25","dataAtualizacao":"2023-10-25","documentos":[{"tipoDocumento":"CARTEIRA_NACIONAL_HABILITACAO","numero":"123456789","dataExpedicao":"2010-03-18","descricao":"Documento Teste","dataInclusao":"2023-12-18","dataAtualizacao":"2023-12-18"}],"endereco":{"logradouro":"Rua xpto","bairro":"Bairro","cep":"12345-789","cidade":"Cidade","uf":"SP","complemento":"Casa","numero":"789"}}
    Session Attrs = {}

Handler:
             Type = com.plano.saude.cadastro.controller.BeneficiarioController
           Method = com.plano.saude.cadastro.controller.BeneficiarioController#createBeneficiary(DadosCadastroBeneficiario, UriComponentsBuilder)

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 201
    Error message = null
          Headers = [Vary:"Origin", "Access-Control-Request-Method", "Access-Control-Request-Headers", Location:"http://localhost/beneficiaries/", Content-Type:"application/json", X-Content-Type-Options:"nosniff", X-XSS-Protection:"0", Cache-Control:"no-cache, no-store, max-age=0, must-revalidate", Pragma:"no-cache", Expires:"0"]
     Content type = application/json
             Body = {"id":null,"nome":"Nome","telefone":"1165459787","dataNascimento":"2002-03-12","dataInclusao":"2023-10-25","dataAtualizacao":"2023-10-25","documentos":[{"id":null,"tipoDocumento":"CARTEIRA_NACIONAL_HABILITACAO","numero":"123456789","dataExpedicao":"2010-03-18","descricao":"Documento Teste","dataInclusao":"2023-12-18","dataAtualizacao":"2023-12-18"}],"endereco":{"logradouro":"Rua xpto","bairro":"Bairro","cep":"12345-789","cidade":"Cidade","uf":"SP","complemento":"Casa","numero":"789"}}
    Forwarded URL = null
   Redirected URL = http://localhost/beneficiaries/
          Cookies = []

org.opentest4j.AssertionFailedError: 
expected: "{"id":null,"nome":"Nome","telefone":"1165459787","dataNascimento":"2002-03-12","dataInclusao":"2023-10-25","dataAtualizacao":"2023-10-25","documentos":null,"endereco":null}"
 but was: "{"id":null,"nome":"Nome","telefone":"1165459787","dataNascimento":"2002-03-12","dataInclusao":"2023-10-25","dataAtualizacao":"2023-10-25","documentos":[{"id":null,"tipoDocumento":"CARTEIRA_NACIONAL_HABILITACAO","numero":"123456789","dataExpedicao":"2010-03-18","descricao":"Documento Teste","dataInclusao":"2023-12-18","dataAtualizacao":"2023-12-18"}],"endereco":{"logradouro":"Rua xpto","bairro":"Bairro","cep":"12345-789","cidade":"Cidade","uf":"SP","complemento":"Casa","numero":"789"}}"
Expected :"{"id":null,"nome":"Nome","telefone":"1165459787","dataNascimento":"2002-03-12","dataInclusao":"2023-10-25","dataAtualizacao":"2023-10-25","documentos":null,"endereco":null}"
Actual   :"{"id":null,"nome":"Nome","telefone":"1165459787","dataNascimento":"2002-03-12","dataInclusao":"2023-10-25","dataAtualizacao":"2023-10-25","documentos":[{"id":null,"tipoDocumento":"CARTEIRA_NACIONAL_HABILITACAO","numero":"123456789","dataExpedicao":" ...

<Click to see difference>


    at java.base/jdk.internal.reflect.DirectConstructorHandleAccessor.newInstance(DirectConstructorHandleAccessor.java:67)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500)
    at com.plano.saude.cadastro.controller.BeneficiarioControllerTest.createBeneficiaryCenario2(BeneficiarioControllerTest.java:97)
    at java.base/java.lang.reflect.Method.invoke(Method.java:578)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

Oi!

No seu teste você está esperando um json que venha sem endereço e sem documento, mas o objeto devolvido está vindo com endereço e documento preenchidos e por isso o teste falha.

Altere o seu DTO do json de resposta para que tenha o endereço e o documento, conforme o dto enviado na requisição.

Então, aí é que está. Eu não estou conseguindo passar para alterar o DTO do json de resposta para retornar o endereço e o documento. Entendo que o problema está para mapear o tratamento de lista para passar o documento, que não sei como tratar. Insira aqui a descrição dessa imagem para ajudar na acessibilidadePara mapear o retorno, eu não sei se eu posso passar o map ou o toList, para trazer como uma lista, como ele foi declarado. Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Aí vai depender de como estão as suas classes DTO. Manda aqui o código delas. DadosDetalhamentoBeneficiario e DadosCadastroBeneficiario

Seguem as classes:

package com.plano.saude.cadastro.domain.beneficiario;

import com.plano.saude.cadastro.domain.documento.DadosDetalhamentoDocumento;
import com.plano.saude.cadastro.domain.endereco.Endereco;

import java.time.LocalDate;
import java.util.List;

public record DadosDetalhamentoBeneficiario(
        Long id,
        String nome,
        String telefone,
        LocalDate dataNascimento,
        LocalDate dataInclusao,
        LocalDate dataAtualizacao,
        List<DadosDetalhamentoDocumento> documentos,
        Endereco endereco) {

    public DadosDetalhamentoBeneficiario(Beneficiario beneficiario) {
        this(
                beneficiario.getId(),
                beneficiario.getNome(),
                beneficiario.getTelefone(),
                beneficiario.getDataNascimento(),
                beneficiario.getDataInclusao(),
                beneficiario.getDataAtualizacao(),
                beneficiario.getDocumentos().stream().map(DadosDetalhamentoDocumento::new).toList(),
                beneficiario.getEndereco()
        );
    }
}
package com.plano.saude.cadastro.domain.beneficiario;

import com.plano.saude.cadastro.domain.documento.DadosCadastroDocumento;
import com.plano.saude.cadastro.domain.endereco.DadosEndereco;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;

import java.time.LocalDate;
import java.util.List;

public record DadosCadastroBeneficiario(
        @NotBlank
        String nome,
        @NotBlank
        String telefone,
        @NotBlank
        LocalDate dataNascimento,
        @NotBlank
        LocalDate dataInclusao,
        LocalDate dataAtualizacao,
        @NotNull
        @Valid
        List<DadosCadastroDocumento> documentos,
        DadosEndereco endereco) {
}

Os atributos endereco e documentos são diferentes nos dois DTOs. No teste então você deve criar esses objetos de acordo com o DTO DadosDetalhamentoBeneficiario, pois o json devolvido no controller é baseado nele.

Entendo. Estou tentando fazer dessa forma, mas não consigo mapear no teste Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Bom, eu tentei passar os atributos de documentos, tanto criando uma variável ou fazendo direto, mas não consigo mapear a lista. Poderiam me ajudar, por favor? Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Insira aqui a descrição dessa imagem para ajudar na acessibilidade

Seria algo assim:

// considerando que sua classe Endereco tenha um construtor que receba um objeto DadosEndereco:
var enderecoEsperado = new Endereco(dadosCadastroBeneficiario.enderecos());

// considerando que sua classe DadosDetalhamentoDocumento tenha um construtor que receba um objeto DadosCadastroDocumento:
var documentosEsperados = dadosCadastroBeneficiario.documentos().stream().map(DadosDetalhamentoDocumento::new).toList();

var dadosDetalhamentoBeneficiario = new DadosDetalhamentoBeneficiario(
                null,
                dadosCadastroBeneficiario.nome(),
                dadosCadastroBeneficiario.telefone(),
                dadosCadastroBeneficiario.dataNascimento(),
                dadosCadastroBeneficiario.dataInclusao(),
                dadosCadastroBeneficiario.dataAtualizacao(),
                documentosEsperados,
                enderecoEsperado);
solução!

Funcionou o teste. Porém, foi necessário ajustar no teste para que a classe DadosDetalhamentoDocumento tenha um construtor que receba uma lista DadosCadastroDocumento. Obrigado pela ajuda!

Seria assim:

// considerando que sua classe DadosDetalhamentoDocumento tenha um construtor que receba uma lista DadosCadastroDocumento: 

**List<DadosDetalhamentoDocumento>** documentosEsperados = dadosCadastroBeneficiario.documentos().stream().map(DadosDetalhamentoDocumento::new).toList();