Boas-vindas ao Curso de Mocks em PHP: entenda os dublês de testes. Mais um treinamento sobre testes utilizando o PHP! Neste treinamento, vamos entender o que são os dublês de teste e como eles podem nos ajudar no seu ciclo de desenvolvimento.
Uma curiosidade interessante é que na data em que estou gravando esse vídeo, saiu um tweet na conta oficial do PHPUnit apresentando o logo oficial do PHPUnit - que durante 19 anos de projeto ainda não tinha uma logo, embora seja um projeto gigante. É só uma curiosidade, bastante interessante sobre a data em que esse treinamento está sendo gravado.
Após as curiosidades e as boas-vindas, nós vamos dar uma analisada no que vamos aprender neste treinamento. Obviamente, novos testes serão criados - e para novos testes serem criados, novos códigos terão sido criados.
Temos uma classe que encerra os leilões - mas quais leilões? Leilões que ainda não foram finalizados e têm mais de uma semana. Para isso, algum código novo vai ser implementado - e junto com esse código, bastante testes serão implementados.
Além de organizar um pouco mais o nosso teste, como já temos feito, vamos aprender como criar classes, dependência falsas e dublês de teste para que eles façam alguma parte do trabalho por nós. Isso para não precisarmos, por exemplo, se conectar ao banco de dados na hora de fazermos um teste - porque queremos testar o código, e não o banco.
Como fazer essa separação bem feita, como testar coisas bem específicas - como, por exemplo: quantas vezes um método foi executado, com quais parâmetros ele foi executado, se o parâmetro passado foi passado de forma correta. Enfim, bastante coisas serão vistas durante este treinamento.
Ele dá uma ótima base para conseguirmos escrever testes de unidade bem escritos. Após este treinamento, você ainda terá um longo caminho na jornada sobre estudos de testes, mas como dizem: bem começado, metade feita.
Vamos começar muito bem e fazer mais esse treinamento para agregarmos bastante conhecimento e imergimos ainda mais nesse mundo de testes automatizados.
Te espero no próximo vídeo para você conferir as novidades desse projeto. Depois nós vamos começar a escrever novos testes. Te espero no próximo vídeo. Um forte abraço!
Bem-vindos(as) de volta! Nós vamos passar bem rapidamente no novo código, que não tínhamos no final do primeiro treinamento. Porém, o que temos agora e que foi implementado para darmos continuidade.
A primeira coisa que temos é um encerrador de leilões. Esse encerrador de leilões está utilizando um leilãoDao
, sendo um data access object - ou seja, um objeto que vai fazer acesso aos dados.
DAO: data access object (em português, "objeto de acesso a dados").
E esse leilão DAO tem um método recuperarNaoFinalizados()
, que já vamos analisar. Ele vai pegar todos os leilões que não foram finalizados ainda e, para cada um desses leilões, se esse leilão tiver mais de uma semana, vai finalizar esse leilão e atualizar no nosso banco de dados.
Passando nesse método recuperarNaoFinalizados()
, no nosso leilãoDao
, ele chama outro método que executa um SQL, em que finalizado é falso ou verdadeiro dependendo do caso – mas, nesse caso, é falso. Aí ele traz os leilões.
Esse método temMaisDeUmaSemana
, também não existia no nosso projeto original. Repare que temos dois campos novos - sendo o "Id", porque agora estamos usando o banco de dados e o "dataInicio" que é simplesmente uma data.
Em temMaisDeUmaSemana
, nós verificamos se a diferença entre a data de início de hoje é maior que sete dias, no total. É um método que adicionamos. O método finaliza
não mudou, é como tínhamos antes. Também temos o método atualiza, que realiza o update na nossa tabela de leilões.
Junto com o código que vamos deixar na plataforma para você baixar, vem um arquivo SQLite - o nosso banco de dados de teste - que já tem a estrutura montada para continuarmos dando o treinamento.
Inclusive, já tem uma conexão sendo montada. Não se preocupe muito com esse código, você já tem uma conexão com esse banco pronta. Se você executar um select nesse banco, você verá que ele vai estar vazio. Não precisa se preocupar com mais nada.
Após entender as novidades desse projeto e analisado um pouco o projeto que não tínhamos no final do primeiro curso, vamos dar continuidade e começar a escrever mais testes para entender melhor sobre o que aprenderemos neste treinamento.
Vamos colocar começar no próximo vídeo!
Bem-vindos(as) de volta! Implementaremos um teste para a classe Encerrador
, porque ela parece ser uma classe crucial para o nosso sistema.
Vamos começar! Vou em “tests > Service”, porque essa classe Encerrador
é um service. Com o botão direito do mouse, vou clicar em cima dela e vou em “New: PHP Class”, porque eu vou criar uma classe de teste. O nome dessa classe de teste vai ser seguindo aquela convenção: a classe que vamos testar vai ser chamada de "EncerradorTest".
Criei na minha classe de teste! Para essa classe ser realmente uma classe de teste do PHPUnit, preciso estender a classe TestCase
desse namespace - class EncerradorTest extends TestCase
. Se você estiver utilizando o PHPStorm, importe desse name space.
Continuando! Vamos implementar um teste propriamente dito, vamos digitar "pubf" - ou se você não estiver utilizando o PHPStorm, digite "public function" e o nome da função.
O nome desse método precisa começar com "Teste", para indicar que é um teste, que é algo que vai ser executado pelo PHPUnit e ter um nome descritivo. Vou dizer que estou testando que leilões com mais uma semana devem ser encerrados, então: public function testLeiloesComMaisDeUmaSemanaDevemSerEncerrados ()
.
Com isso, o método que eu vou testar é do meu Encerrador
. Eu quero testar o método encerra
, então digito: $encerrador = new Encerrador (); $encerrador=>encerra();
.
Repare que o PHPStorm já importou para mim. Só que este "encerra", se lembrarmos, ele vai encerrar os leilões não finalizados que estão no meu banco e que são buscados pelo meu leilão DAO. Vamos criar alguns leilões para que ele possa encerrar.
Vou criar um leilão de uma Fiat 147, vocês já devem ter percebido que eu gosto bastante desse carro. Vou criar um leilão. Lembre-se de importar do namespace correto, do namespace model. Vou quebrar a linha, vai ser para uma’$fiat 147 = new Leilao ()’ - e a data de início, o segundo parâmetro que precisamos passar agora.
É um novo date time immutable, ou seja, é um dia só que eu não posso mudar esse objeto depois de criado. Mas você não precisa ficar muito nisso, só foque que é um dia de oito dias atrás, então: ‘( descricao: 'Fiat 147 0km' e ‘new \DateTimeImmutable( time: 8 days ago')’.
No PHP, podemos passar strings legíveis, humanamente inteligíveis que ele sabe se virar e criar uma data a partir disso. Isso é bem legal! Essa contra barra na frente de ‘DateTimeImmutable’ é só para indicar que está no namespace global, porque é uma classe do próprio PHP.
Continuando, eu vou criar agora outro leilão para uma variante. Eu nunca lembro se variante tem o ‘e’ no final ou não. Vou escrever sem, mas caso o certo seja com o ‘e’ no final, você pode colocar aí sem problema.
Vou criar um leilão para essa variante de 1972, 0km. Nesse leilão o date está immutable, é de 10 dias atrás: $variant = new Leilao(
, na linha debaixo descricao: 'Variant 1972 0km' e ‘new \DateTimeImmutable( time: '10 days ago')
.
Criei um leilão para a variante para o Fiat 147. Preciso salvar no banco de dados porque o meu ‘Encerrador’ está buscando os dados do banco para encerrar.
Vamos pegar o leilão DAO, porque é ele quem faz esse trabalho de salvar e buscar os dados: $leilaoDao = new Leilao
. Repare que se eu importar e apertar a tecla "Enter", o PHPStorm vai colocar um nome completo da classe para mim - $leilaoDao = new \Alura\Leilao\Dao\Leilao()
. Só que quero importar, eu quero fazer igual estou fazendo com esses outros.
Eu já tenho o Leilão e no meu namespace ‘Dao’, eu tenho outro Leilão, uma classe Leilao
- e eu fiz isso de propósito. Se eu tentar importar com o PHPStorm, ele vai retornar uma mensagem. Eu já tenho uma classe chamada Leilao
. Do que eu vou chamar essa classe? Eu posso informar: LeilaoDao
.
Se você não estiver utilizando o PHPStorm, é só fazer um new LeilaoDao
e lá em cima importar dessa forma: ‘use
’, o nome completo da classe, ‘as
’ e o nome que você quer dar para ela, como você quer chamar.
Ficará: use Alura\Leilao\Dao\Leilao as LeilaoDao;
. Dessa forma, em namespaces diferentes, posso ter classes com o mesmo nome. Por isso, coloquei com o mesmo nome de propósito, para você entender. Porque é exatamente esse o propósito de namespace de pacotes diferentes.
Dando continuidade, eu tenho o meu ‘LeilaoDao’ e, a partir dele ,eu posso salvar o meu leilão da Fiat 147 e o meu leilão da variante. Digitei: $leilaoDao=>salva($fiat147);
e $leilaoDao=>salva($variant);
.
Salvei. O meu "encerrador" vai encerrar: $encerrador = new Encerrador();
e $encerrador=>encerra();
.
Agora preciso verificar. Eu já tenho o meu range, ou seja, eu preparei meu teste. E o meu act, ou seja, eu executei o código que eu quero testar. Como que eu faço o meu assert? Como que eu verifico que o que aconteceu realmente aconteceu?
Primeira coisa: preciso buscar os leilões já finalizados. Nesses leilões finalizados, preciso ter dois: o da Fiat 147 e o da variante. Vou pegar o meu ‘LeilaoDao’ e um método de recuperar finalizados: $leiloes = $leilaoDao->recuperarfinalizados();
.
Nesse recuperarfinalizados
ele me devolve ‘leiloes’. Nesses ‘leiloes’, eu sei que preciso ter dois: o Fiat 147 e a variante. Vou verificar com: self::assertCount
, ou seja, verifico que existe essa quantidade em um array, em um objeto que seja contável; verifico que tem dois desses meus ‘leiloes’. Digitei: self::assertCount( expectedCount 2, $leiloes);
.
Garantiu que têm dois? Agora: self::assertEquals
, ou seja, garante que o primeiro desses leilões é o da Fiat 147 e o segundo é a variante. Garante que self::assertEquals( expected: 'Fiat 147 0Km
, e $leiloes[0]=>recuperardescricao() );
.
Vou copiar essa verificação para testar o nosso segundo leilão também, que tem que ser para variante 1972 0km: self::assertEquals( expected: 'Variant 1972 0Km
e $leiloes[0]->recuperardescricao();
.
Com isso, estou garantindo que o meu ‘Encerrador’ está realmente encerrando os leilões e executando esse código. Teste criado, agora posso executar meus testes.
Abrindo o terminal, acessaremos a pasta do projeto e rodaremos o PHPUnit - ou posso vir com o PHPStorm e rodar esse teste direto, mas eu vou fazer um meio-termo.
Para quem não está utilizando o PHPStorm poder acompanhar e editar os comandos junto comigo, eu vou digitar os comandos; só que eu não vou abrir um Prompt de comando, eu vou abrir o Prompt de comando diretamente dentro da minha IDE. Embaixo tem "Terminal".
Eu só preciso executar: vendor\bin\phpunit
. Quando eu executo os testes, tudo continua funcionando. Todos os meus códigos anteriores continuam funcionando e também esse código que eu acabei de criar, esse teste que eu criei passa também, tenho testes passando.
Só para garantir, eu vou executar de novo. Eu acabei de criar esse teste, ele executou com sucesso. Eu rodei de novo e falhou. O que aconteceu? Vamos ver a mensagem de erro, existe uma falha.
Mensagem: "Falha ao verificar que o tamanho real de 4 leilões bate com o esperado de 2 leilões". Entendi o que aconteceu, a mensagem é muito clara e essa é uma das vantagens do teste.
Ele está me dizendo que ao invés de ter 2 leilões, tenho 4. Porque na primeira vez que eu executei o teste, ele salvou esses dois leilões. Na segunda vez que executei, salvou de novo.
Nesse tipo de testes eu não estou testando só o código, eu estou testando o código e o banco de dados. Isso já é outro de testes, nós queremos trabalhar com testes de unidade.
Como será que posso fazer com que o meu método encerra()
finalize, sem depender do banco de dados? E sem precisar que o banco de dados esteja funcionando, para conseguir testar? Vamos conversar um pouco melhor sobre isso no próximo vídeo!
O curso Mocks em PHP: entenda os dublês de testes possui 71 minutos de vídeos, em um total de 40 atividades. Gostou? Conheça nossos outros cursos de PHP em Programação, ou leia nossos artigos de Programação.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.