32
respostas

[Dúvida] Expected Null...

Olá!

Não sei o que houve, pois tinha feito o teste unitário desse cenário e tinha dado certo. Porém no final dessa aula, ao clicar em testar tudo deu erro no cenário que irei compartilhar do print...está esperando null. Não entendi o log então não estou conseguindo identificar o erro...

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

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

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

32 respostas

Oi!

Provavelmente seus testes estão utilizando o mesmo banco de dados da aplicação, cuja tabela de médicos deve ter registros e por isso o teste falha.

Confere a classe de teste se a configuração está para utilizar um banco de dados de testes separado.

Oi Rodrigo!

Então, eu fui fazendo contigo a medida que ia assistindo a aula e quando testei deu tudo certo.

Mas quando foi no final da aula implementando teste 200, onde você testa todos os testes escritos até o momento, esse dos prints falhou. Só que eu não mexi em nada. Antes funcionou. Então fiquei sem entender o erro...

Está usando o banco da aplicação conforme você passou em aula, ao invés do data base in-memory.

No aguardo...

Confere se na sua classe de teste tem essas anotações:

@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@ActiveProfiles("test")

E verifica se você tem o arquivo application-test.properties, com essa única propriedade que altera o database de testes:

spring.datasource.url=jdbc:mysql://localhost/vollmed_api_test

Tem sim! Eu fui fazendo juntamente contigo durante a aula.

Quando montei e testei funcionou. Mas quando fui testar todos os testes, esse falhou. E não consigo entender porque desde que o código aparentemente não tem nada de errado.

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

Acho que os dados devem ter sido persistidos e não apagados do database de testes. Entre no seu database de testes e apague todos os registros:

delete from consultas;
delete from medicos;
delete from pacientes;

Adicione a anotação @Transactional na classe de teste e veja se com isso os testes vão passar (rode várias vezes os testes)

Fiz conforme orientado. Deletei todos os possíveis registros na vollmed_api_test e foi deletado com sucesso. Coloquei o @Transactional na classe de teste e mesmo assim, ele continua acusando o mesmo tipo de erro conforme o print que já postei lá em cima... Não entendo porque. Pois ao ir montando o código desse cenário, o testei e ele funcionou. Só acusou erro depois que foram montados todos os testes passados em aula...

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

Tu consegue compartilhar o teu projeto? Pode ser via GitHub

Baixei o seu projeto, rodei os testes várias vezes e está tudo funcionando certinho.

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

Ué então por que não está rodando todos os testes ok no meu notebook?

Fiquei sem entender agora.

Eu achei estranho mesmo não estar funcionando porque estava tudo funcionando nos testes unitários. O problema se deu quando coloquei pra testar todos os testes juntos e deu os problemas já printados acima.

Pior que quero fazer o build do projeto mas o erro persiste. Não entendi...

Acabei de testar e continua olha...não tô entendendo isso.

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

Aparece esse Comparison Failure, esperando null mas vindo med.voll.api.domain.medico.Medico@43

Não sei nem do que se trata esse @43...

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

Rode apenas esse teste escolherMedicoAleatorioLivreNaDataCenario1 e manda aqui o log que sai no console

Hibernate: insert into medicos (ativo, crm, email, bairro, cep, cidade, complemento, logradouro, numero, uf, especialidade, nome, telefone) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: insert into pacientes (ativo, cpf, email, bairro, cep, cidade, complemento, logradouro, numero, uf, nome, telefone) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) Hibernate: insert into consultas (data, medico_id, motivo_cancelamento, paciente_id) values (?, ?, ?, ?) Hibernate: select m1_0.id, m1_0.ativo, m1_0.crm, m1_0.email, m1_0.bairro, m1_0.cep, m1_0.cidade, m1_0.complemento, m1_0.logradouro, m1_0.numero, m1_0.uf, m1_0.especialidade, m1_0.nome, m1_0.telefone from medicos m1_0 where m1_0.ativo=1 and m1_0.especialidade=? and m1_0.id not in (select c1_0.medico_id from consultas c1_0 where c1_0.data=? and c1_0.motivo_cancelamento is null) order by rand() limit 1

org.opentest4j.AssertionFailedError: expected: null but was: med.voll.api.domain.medico.Medico@45 Expected :null Actual :med.voll.api.domain.medico.Medico@45

at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at med.voll.api.domain.medico.MedicoRepositoryTest.escolherMedicoAleatorioLivreNaDataCenario1(MedicoRepositoryTest.java:54)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

2024-07-10T12:19:28.918-03:00 INFO 124 --- [api] [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2024-07-10T12:19:28.929-03:00 INFO 124 --- [api] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2024-07-10T12:19:29.033-03:00 INFO 124 --- [api] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.

Manda o logo do Spring, que começa assim:

 .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.0)

2024-07-10T12:15:30.714-03:00  INFO 40300 --- [api] [           main] m.v.a.d.medico.MedicoRepositoryTest      : Starting MedicoRepositoryTest using Java 17.0.8 with PID 40300 (started by rodrigo in /home/rodrigo/Downloads/VollMed-API---Curso-Spring-Boot-e-Java-Alura-main)
2024-07-10T12:15:30.715-03:00  INFO 40300 --- [api] [           main] m.v.a.d.medico.MedicoRepositoryTest      : The following 1 profile is active: "test"
2024-07-10T12:15:30.977-03:00  INFO 40300 --- [api] [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-07-10T12:15:31.022-03:00  INFO 40300 --- [api] [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 39 ms. Found 4 JPA repository interfaces.

12:19:08.132 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [med.voll.api.domain.medico.MedicoRepositoryTest]: MedicoRepositoryTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration. 12:19:08.663 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration med.voll.api.ApiApplication for test class med.voll.api.domain.medico.MedicoRepositoryTest 12:19:08.933 [main] INFO org.springframework.boot.devtools.restart.RestartApplicationListener -- Restart disabled due to context in which it is running . ____ _ __ _ _ /\ / _' __ _ ()_ __ __ _ \ \ \ ( ( )__ | '_ | '| | ' / ` | \ \ \ \/ _)| |)| | | | | || (_| | ) ) ) ) ' || .|| ||| |_, | / / / / =========||==============|_/=//_//

:: Spring Boot :: (v3.3.0)

2024-07-10T12:19:10.114-03:00 INFO 124 --- [api] [ main] m.v.a.d.medico.MedicoRepositoryTest : Starting MedicoRepositoryTest using Java 17.0.7 with PID 124 (started by josh_ in C:\Users\josh_\Desktop\api) 2024-07-10T12:19:10.116-03:00 INFO 124 --- [api] [ main] m.v.a.d.medico.MedicoRepositoryTest : The following 1 profile is active: "test" 2024-07-10T12:19:11.781-03:00 INFO 124 --- [api] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode. 2024-07-10T12:19:11.992-03:00 INFO 124 --- [api] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 186 ms. Found 4 JPA repository interfaces. 2024-07-10T12:19:16.182-03:00 INFO 124 --- [api] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2024-07-10T12:19:17.582-03:00 INFO 124 --- [api] [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection com.mysql.cj.jdbc.ConnectionImpl@4342c13 2024-07-10T12:19:17.587-03:00 INFO 124 --- [api] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2024-07-10T12:19:17.785-03:00 INFO 124 --- [api] [ main] org.flywaydb.core.FlywayExecutor : Database: jdbc:mysql://localhost/vollmed_api_test (MySQL 8.0) 2024-07-10T12:19:18.156-03:00 INFO 124 --- [api] [ main] o.f.core.internal.command.DbValidate : Successfully validated 8 migrations (execution time 00:00.147s) 2024-07-10T12:19:18.199-03:00 INFO 124 --- [api] [ main] o.f.core.internal.command.DbMigrate : Current version of schema vollmed_api_test: 8 2024-07-10T12:19:18.209-03:00 INFO 124 --- [api] [ main] o.f.core.internal.command.DbMigrate : Schema vollmed_api_test is up to date. No migration necessary. 2024-07-10T12:19:18.529-03:00 INFO 124 --- [api] [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default] 2024-07-10T12:19:18.767-03:00 INFO 124 --- [api] [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.5.2.Final 2024-07-10T12:19:19.000-03:00 INFO 124 --- [api] [ main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled 2024-07-10T12:19:20.144-03:00 INFO 124 --- [api] [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer 2024-07-10T12:19:23.165-03:00 INFO 124 --- [api] [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration) 2024-07-10T12:19:23.182-03:00 INFO 124 --- [api] [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default' 2024-07-10T12:19:24.024-03:00 INFO 124 --- [api] [ main] o.s.d.j.r.query.QueryEnhancerFactory : Hibernate is in classpath; If applicable, HQL parser will be used. 2024-07-10T12:19:25.249-03:00 INFO 124 --- [api] [ main] m.v.a.d.medico.MedicoRepositoryTest : Started MedicoRepositoryTest in 16.349 seconds (process running for 19.419) OpenJDK 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended

Está tudo certo. Pelo log, o teste rodou no profile de testes e está utilziando o database de testes vollmed_api_test.

Entra no MySQL, acessa esse database e veja se tem algum registro:

mysql -u root -p vollmed_api_test
select * from medicos;

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

Pois é, achei que tinha algum registro na tabela, mas nem tem.

Seu teste está falhando porque a consulta de médico aleatório livre está devolvendo o próprio médico que acabou de ser cadastrado, mas não deveria retornar, pois ele tem uma consulta que acabou de ser cadastrada na mesma data.

Só para confirmar isso, faz o seguinte:

  1. Adicione essa anotação do Lombok nas classes Consulta, Medico e Paciente: @ToString
  2. Altere na classe de testes o método cadastrarConsulta, para retornar a consulta:
    private Consulta cadastrarConsulta(Medico medico, Paciente paciente, LocalDateTime data) {
        return em.persist(new Consulta(null, medico, paciente, data, null));
    }
    
  3. Coloque esses System.out no final do método de teste:
    var medicoLivre = medicoRepository.escolherMedicoAleatorioLivreNaData(Especialidade.CARDIOLOGIA, proximaSegundaAs10);
    
    System.out.println("Medico: " +medico);
    System.out.println("Paciente: " +paciente);
    System.out.println("Consulta: " +consulta);
    System.out.println("Medico Livre: " +medicoLivre);
    
    assertThat(medicoLivre).isNull();
    

Rode o teste e mande aqui a saída dos system.out no console

Oiiii!!

Eu apaguei o cadastrar consulta e refatorei como você passou acima, coloquei o @ToString do lombok nas classes mencionadas, mas ele está dando erro de compilação conforme print que vou mandar...nem eu entendi porque os parâmetros estão certos de acordo com o construtor da classe consulta...

Dá uma olhada...

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

Você acabou criando o método cadastrarConsulta dentro do método de teste e por isso o erro de compilação.

Na verdade já existe esse método cadastrarConsulta aí na sua classe de testes e é ele que você deve modificar.

Ah sim verdade. Arrumei, mas ao montar esse sout ele dá erro...

System.out.println("Consulta: " +consulta);

o consulta não está entrando...

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

Método alterado conforme orientado. Segue print. Agora alterei no lugar certo. Mas consulta não está entrando no sout...

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

No método de teste, acima da linha que cria a variável medicoLivre, tem a chamada ao método cadastrarConsulta, mas ele não guarda o retorno. Altere essa linha para:

var consulta = cadastrarConsulta(medico, paciente, proximaSegundaAs10);

Boa! Esqueci desse detalhe. Alterei e rodei apenas esse cenario de teste...

O Log foi esse. Continuou com erro...

Médico: Medico(id=11, nome=Medico, email=medico@voll.med, telefone=61999999999, crm=225566, especialidade=CARDIOLOGIA, endereco=med.voll.api.domain.endereco.Endereco@6121b045, ativo=true) Paciente: Paciente(id=8, nome=Paciente, email=paciente@voll.med, telefone=61999999999, cpf=44455599900, endereco=med.voll.api.domain.endereco.Endereco@63714a1, ativo=true) Consulta: Consulta(id=8, medico=Medico(id=11, nome=Medico, email=medico@voll.med, telefone=61999999999, crm=225566, especialidade=CARDIOLOGIA, endereco=med.voll.api.domain.endereco.Endereco@6121b045, ativo=true), paciente=Paciente(id=8, nome=Paciente, email=paciente@voll.med, telefone=61999999999, cpf=44455599900, endereco=med.voll.api.domain.endereco.Endereco@63714a1, ativo=true), data=2024-07-15T10:00:29.353146800, motivoCancelamento=null) Médico livre: Medico(id=11, nome=Medico, email=medico@voll.med, telefone=61999999999, crm=225566, especialidade=CARDIOLOGIA, endereco=med.voll.api.domain.endereco.Endereco@6121b045, ativo=true)

org.opentest4j.AssertionFailedError: expected: null but was: Medico(id=11, nome=Medico, email=medico@voll.med, telefone=61999999999, crm=225566, especialidade=CARDIOLOGIA, endereco=med.voll.api.domain.endereco.Endereco@6121b045, ativo=true) Expected :null Actual :Medico(id=11, nome=Medico, email=medico@voll.med, telefone=61999999999, crm=225566, especialidade=CARDIOLOGIA, endereco=med.voll.api.domain.endereco.Endereco@6121b045, ativo=true)

at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at med.voll.api.domain.medico.MedicoRepositoryTest.escolherMedicoAleatorioLivreNaDataCenario1(MedicoRepositoryTest.java:61)
at java.base/java.lang.reflect.Method.invoke(Method.java:568)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)

2024-07-10T19:35:29.852-03:00 INFO 25956 --- [api] [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default' 2024-07-10T19:35:29.855-03:00 INFO 25956 --- [api] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2024-07-10T19:35:29.878-03:00 INFO 25956 --- [api] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.

Process finished with exit code -1

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

É exatamente o que eu imaginava, ele está devolvendo o mesmo médico na consulta de médico livre, mas não era para trazer.

O código está certo e esse erro não faz sentido :D

A única possibilidade seria por conta de versão do MySQL, que poderia executar a consulta diferente em versões distintas. Rode esse comando e veja qual a versão do seu MySQL:

mysql --version

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

E agora? Queria fazer o build do projeto e não dá por causa desse único teste falhando...

Se alguém puder me ajudar quanto a essa questão de versão do mysql agradeço. No aguardo...

A versão do meu é 8.0.37, mas como não é uma versão diferente da 8, não sei se isso causaria o impacto.

É algum problema do seu ambiente, pois aqui e em outro computador que testei funcionou normalmente. Você consegue simular em outro computador para validar?

Uma última tenteativa seria apagar o banco de testes e criar novamente (apenas o database, pois as tabelas serão criadas pelo Flyway):

drop database vollmed_api_test;
create database vollmed_api_test;

Oi!!! Fiz tudo novamente. Dropei e criei de novo. Exclui as classes testes e montei tudo novamente, mas o mesmo erro no cenario1 de MedicoRepositoryTest continuou...

Acho que pra fazer o build vou ter que excluir esse cenário, mas me frusta saber que está dando erro e não achando. Porque conforme você mesmo disse, está tudo certinho no código e você até testou em outro computador. Eu só tenho o meu notebook pessoal, então não consigo testar em outro diferente.

Mas muito obrigado por todas as sugestões e suporte.

Vou excluir esse cenário1 e buildar...