Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

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