2
respostas

[Dúvida] Dicas para testar classes Service @Service

Oi!

Gostaria de pedir algumas dicas para testar classes Service (@Service) para minha aplicação, por favor. Eu comecei a fazer os testes pela classe AgendaDeConsultas, explicada no curso, pegando os atributos utilizados na classe principal, alterando a anotação de @Autowired para @MockBean, colocando somente @Autowired para o atributo da classe AgendaDeConsultas, fazendo dessa forma:

public class AgendaDeConsultas {

    @MockBean
    private ConsultaRepository consultaRepository;

    @MockBean
    private MedicoRepository medicoRepository;

    @MockBean
    private BeneficiarioRepository beneficiarioRepository;

    @MockBean
    private List<ValidadorAgendamentoDeConsulta> validadores;

    @MockBean
    private List<ValidadorCancelamentoDeConsulta> validadoresCancelamento;

    @Autowired
    private AgendaDeConsultas agendaDeConsultas;

}

Depois disso, eu acabo me perdendo na hora de criar as simulações e testar os métodos, junto com os cenários de sucesso e erro.

2 respostas

Oi, Alexandre! Como vai?

Sei como pode ser confuso no início testar classes de serviço em uma aplicação Spring Boot. Vou te dar algumas dicas para te ajudar a estruturar melhor seus testes.

Primeiro, é importante que você utilize a anotação correta para criar seus testes. Para testar classes de serviço, você pode usar o @ExtendWith(MockitoExtension.class) do JUnit 5 e o @Mock do Mockito para criar os mocks. Além disso, você deve usar a anotação @InjectMocks para injetar os mocks na classe que você está testando. Aqui está um exemplo de como você pode estruturar isso:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.mockito.Mockito.*;

@ExtendWith(MockitoExtension.class)
public class AgendaDeConsultasTest {

    @Mock
    private ConsultaRepository consultaRepository;

    @Mock
    private MedicoRepository medicoRepository;

    @Mock
    private BeneficiarioRepository beneficiarioRepository;

    @Mock
    private List<ValidadorAgendamentoDeConsulta> validadores;

    @Mock
    private List<ValidadorCancelamentoDeConsulta> validadoresCancelamento;

    @InjectMocks
    private AgendaDeConsultas agendaDeConsultas;

    @BeforeEach
    void setUp() {
        // Configurar mocks se necessário
    }

    @Test
    void testAgendamentoDeConsultaComSucesso() {
        // Configurar os mocks para o cenário de sucesso
        when(consultaRepository.save(any())).thenReturn(new Consulta());
        // Adicione mais configurações de mocks conforme necessário

        // Chamar o método a ser testado
        agendaDeConsultas.agendarConsulta(/* parâmetros necessários */);

        // Verificar se os métodos dos mocks foram chamados corretamente
        verify(consultaRepository).save(any());
        // Adicione mais verificações conforme necessário
    }

    @Test
    void testAgendamentoDeConsultaComErro() {
        // Configurar os mocks para o cenário de erro
        when(consultaRepository.save(any())).thenThrow(new RuntimeException("Erro ao salvar consulta"));
        // Adicione mais configurações de mocks conforme necessário

        // Chamar o método a ser testado e verificar se a exceção é lançada
        assertThrows(RuntimeException.class, () -> {
            agendaDeConsultas.agendarConsulta(/* parâmetros necessários */);
        });

        // Verificar se os métodos dos mocks foram chamados corretamente
        verify(consultaRepository).save(any());
        // Adicione mais verificações conforme necessário
    }
}

Nesse exemplo, você pode ver como configurar os mocks e injetá-los na classe AgendaDeConsultas. Em seguida, você pode configurar os mocks para retornar valores específicos ou lançar exceções, dependendo do cenário que você está testando. Por fim, você pode usar o verify para garantir que os métodos dos mocks foram chamados corretamente.

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.

Oi!

Então, eu tentei fazer alguns testes das classes service que eu tenho para fazer, acabei revisando e encontrei alguns problemas na hora de executar para testar, quando eu segui os exemplos que passou. Primeiro erro, na classe abaixo, retorna que não localiza a classe para testar, nunca tinha visto esse tipo de erro:

@ExtendWith(MockitoExtension.class)
class AccountServiceTest {

    @Mock
    private AccountRepository accountRepository;

    @InjectMocks
    private AccountService accountService;

    @Test
    @DisplayName("Deve salvar conta com sucesso")
    void saveAccountSuccess() {
        when(accountRepository.save(any())).thenReturn(new Account());
        accountService.saveAccount(account);

        verify(accountRepository.save(any()));
    }

    @Test
    @DisplayName("Erro ao tentar salvar conta")
    void saveAccountError() {
        when(accountRepository.save(any())).thenThrow(new ValidationException("Conta já cadastrada!"));

        assertThrows(ValidationException.class, () -> {
            accountService.saveAccount(accountNull);
        });

        verify(accountRepository.save(any()));
    }

Outro erro que encontrei, ao testar essa classe, não está compilando, que não consigo mockar o primeiro resultado vindo da classe original: Insira aqui a descrição dessa imagem para ajudar na acessibilidadePor acaso vc viu algo parecido na hora de fazer os testes?