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

AssertionFailedError - ele está esperando receber um json, mas recebe outro

Criei a função "agendar_cenario2" do mesmo jeito que está no repositório do github, mas continua dando este erro:

org.opentest4j.AssertionFailedError: 
expected: "{"id":null,"idMedico":2,"idPaciente":5,"data":"2024-02-13T22:53:45.7402564"}"
 but was: "{"idMedico":2,"idPaciente":5,"data":"2024-02-13T22:53:45.7402564","especialidade":"CARDIOLOGIA"}"

Ele fala que esperava receber um json, mas recebeu outro. Só que não sei o que fazer já que os dois DTOs usados nessa função tem uma estrutura diferente. Minha classe de teste está assim:

package med.voll.api.controllers;

import static org.assertj.core.api.Assertions.*;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;

import java.time.LocalDateTime;

import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.json.AutoConfigureJsonTesters;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.json.JacksonTester;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.web.servlet.MockMvc;

import med.voll.api.dtos.consulta.DadosAgendamentoConsulta;
import med.voll.api.dtos.consulta.DadosDetalhamentoConsulta;
import med.voll.api.enums.Especialidade;
import med.voll.api.services.AgendaDeConsultas;

@SpringBootTest
@AutoConfigureMockMvc 
@AutoConfigureJsonTesters 
public class ConsultaControllerTest {

    @Autowired
    private MockMvc mvc;

    @Autowired
    private JacksonTester<DadosAgendamentoConsulta> dadosAgendamentoConsultaJson;

    @Autowired
    private JacksonTester<DadosDetalhamentoConsulta> dadosDetalhamentoConsultaJson;

    @MockBean
    private AgendaDeConsultas agendaDeConsultas;

    @Test
    @DisplayName("Deveria devolver codigo http 400 quando informacoes estao invalidas")
    @WithMockUser 
    void agendar_cenario1() throws Exception {
        var response = mvc.perform(post("/consultas"))
            .andReturn() 
            .getResponse(); 

        assertThat(response.getStatus()).isEqualTo(HttpStatus.BAD_REQUEST.value()); 
    }

    @Test
    @DisplayName("Deveria devolver codigo http 200 quando informacoes estao validas")
    @WithMockUser
    void agendar_cenario2() throws Exception {
        var data = LocalDateTime.now().plusHours(1);
        var especialidade = Especialidade.CARDIOLOGIA;

        var dadosDetalhamento = new DadosDetalhamentoConsulta(null, 2l, 5l, data);
        when(agendaDeConsultas.agendar(any())).thenReturn(dadosDetalhamento);

        var response = mvc
            .perform(
                post("/consultas")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(dadosAgendamentoConsultaJson.write(
                        new DadosAgendamentoConsulta(2l, 5l, data, especialidade)
                    ).getJson())
            )
            .andReturn().getResponse();

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

        var jsonEsperado = dadosDetalhamentoConsultaJson.write(
                dadosDetalhamento
        ).getJson();

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

Olá! Tudo bem?

O erro indica que o JSON esperado contém um campo "id" que é nulo, mas o JSON que foi retornado não contém esse campo. Além disso, o JSON retornado contém um campo "especialidade" que não está presente no JSON esperado.

A causa desse problema parece estar na forma como você está criando o objeto DadosDetalhamentoConsulta em seu teste. Você está passando null para o campo "id", mas o objeto retornado pela função agendar() não parece ter esse campo como nulo. Além disso, o objeto retornado parece ter um campo "especialidade", que não está sendo considerado no seu teste.

Para resolver esse problema, você pode tentar ajustar a criação do objeto DadosDetalhamentoConsulta em seu teste para que ele corresponda à estrutura do objeto que está sendo retornado pela função agendar().

Por exemplo, se o campo "id" não deveria ser nulo e o campo "especialidade" deveria estar presente, você poderia criar o objeto DadosDetalhamentoConsulta da seguinte maneira:

var dadosDetalhamento = new DadosDetalhamentoConsulta(1L, 2L, 5L, data, Especialidade.CARDIOLOGIA);

Note que estou supondo um valor para o campo "id". Você deve ajustar esse valor conforme o esperado pela sua aplicação. Além disso, incluí o campo "especialidade", que estava faltando.

Depois disso, você deve ajustar a criação do JSON esperado em seu teste para que ele também inclua o campo "especialidade":

var jsonEsperado = dadosDetalhamentoConsultaJson.write(dadosDetalhamento).getJson();

Lembre-se que essas são sugestões baseadas na informação que você forneceu. Pode ser que você precise fazer ajustes adicionais para resolver o problema.

Então, caso não resolva, considere compartilhar o seu projeto, que você bem já comentou que está no repositório do GitHub.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.
solução!

Dei uma revisada no controlador das consultas e percebi que o erro estava na função 'agendar()'. Antes ela estava dessa forma:

public ResponseEntity agendar(@RequestBody @Validated DadosAgendamentoConsulta dados) {
        agenda.agendar(dados);
        return ResponseEntity.ok(dados);
    }

Dava problema porque retornava os mesmo dados de seu parâmetro, então só precisava criar uma variável de 'dto' para ser retornada depois.

public ResponseEntity agendar(@RequestBody @Validated DadosAgendamentoConsulta dados) {
        var dto = agenda.agendar(dados);
        return ResponseEntity.ok(dto);
    }