[MÚSICA] [MÚSICA] Olá a todos meu nome é Eduardo Guerra. Esse é o curso de desenvolvimento de software guiado por testes. Na aula de hoje vamos falar aí das Diretivas de Mock Object ou seja, o que é que o Mock Object precisa fazer? Quais os papeis que ele cumpre ali dentro do teste, como ele se insere dentro do teste? Ele precisa verificar alguma coisa? Ele precisa ter determinado comportamento? Então, eu gosto de, então, assim basicamente hoje a gente vai entender quais são os tipos de coisa que o Mock Object precisa fazer. Eu gosto de dizer que o Mock Object parecido com o nosso amigo RobotCop, ele tem três diretivas que ele precisa seguir. podem estar ali na programação do nosso Mock Object. Então, a primeira diretiva é imitar a interface da dependência, depois simular o comportamento do cenário de teste, e por fim verificar as chamadas esperadas da classe. Então no nosso exemplo a gente teria aqui por exemplo, uma classe de negócios, que é o que a gente está desenvolvendo. E ela tem alí uma classe que ela executa alguns processos, que você passa o nome do processo e ela vai estar executando aquilo algum lugar. Mais ou menos, executa o cadastrar o usuário, então ele de alguma forma vai executar aquilo. E é justamente essa classe que executa esses processos que a gente vai estar criando o Mock Object aqui na nossa aula. Então a gente vai vendo a partir desse exemplo cada uma das diretivas, e como a gente pode estar fazendo para implementar aí cada uma. Bom, então a primeira coisa que o Mock precisa é ter a mesma interface da dependência. Então por exemplo, eu vou pegar o meu Mock Object que seria alí o ExecMock, e vou estar implementando a interface Executor. E aí obviamente esse, por implementar a interface executor o meu Mock precisa ter todos os métodos que essa interface Executor possui. Eu também já entrando aí na segunda diretiva, eu preciso simular comportamentos para o cenário de teste. Então no caso se a gente observar o método executar aqui, ele retorna "booleano". Então, eu tenho que como de alguma forma lá no meu teste configurar, "Olha, eu quero que ele retorne por exemplo, alí no lugar do resultado o valor que eu passar pra ele". Então se eu quiser por exemplo, que ele retorne True, eu vou alí e chamo "setResultado True" e se eu quiser que ele retorne False, eu chamo "setResultado False". Então, assim pode ser obviamente com qualquer tipo de retorno que o meu Mock precisar retornar alí no método. No caso por exemplo dele ter vários métodos e poder retornar coisas diferentes às vezes numa mesma chamada da classe. Você tem que guardar isso daí de alguma forma para que na hora que a classe chamar o Mock Object, ele retorne o que você está querendo. Então o que é interessante falar é dizer que esse retorno do Mock ele é parte do cenário de teste. Então se você fala assim, "Olha eu estou criando caso de teste no caso da execução da dependência dar verdadeiro ou no caso da execução da dependência dar falso". Isso faz parte do cenário do teste. Lembrando que como o resultado de execução do teste, do método, do Mock, não necessáriamente vai ser retorno mas pode por exemplo ser uma exceção que está sendo lançada, então nesse caso eu também criei aqui método setException, que eu configuro alí uma exceção dentro de uma variável, e eu verifico dentro do meu método executar se aquela exceção for diferente de nula ou seja, se o meu teste configurar alguma coisa alí, ele vai lançar aquela exceção como resultado, também parte do cenário de teste ou seja, eu quero testar a minha classe no caso da dependência dela jogar uma exceção, quero ver se ela se comporta de forma correta nesses casos. E aí por fim, a última diretiva do Mock é verificar as chamadas esperadas pela classe, então por exemplo, eu chamei vou supor, minha classe lá ela vai chamar essa classe executora aí por exemplo com sei lá duas vezes com a string calcular alguma coisa, ou cadastrar alguma coisa, então eu tenho que verificar no teste se a minha classe fez as chamadas corretas ou com os parâmetros corretos, ou quantidade correta na dependência dela. Então o que a gente precisa fazer? no método Executar, repare que agora, antes era assim, eu configurava alguma coisa para o Executar fazer, agora o Executar ele vai guardar as informações da chamada, então se eu precisar desse tipo de verificação, eu preciso que ele guarde alí o resultado ou os parâmetros, ou a quantidade de chamadas, dependendo do que eu quero verificar. No caso alí ele recebe uma String como parametro e eu estou guardando essa String uma lista chamada alí Execuções. E aí eu crio método, esse método ele é do Mock assim como aqueles métodos né, eu vou voltar pouquinho aqui. O método setException ou o método setResultado, esses métodos são métodos do Mock não são métodos da interface são métodos que quem vai utilizar é o teste. Vamos voltar aqui então para o nosso método Verifica, que assim como aqueles que eu mostrei aqui, são métodos do Mock, e aí por exemplo eu vou passar para ele uma lista de string com as execuções e vou verificar aqui no caso, se todas aquelas execuções foram realmente chamadas. Nesse caso aqui repare que ele tem "for" que ele vai passando pelas verificações e ele tem "if" que verifica se aquela execução está contida na lista de execuções que ele guardou. Então, basicamente o que eu estou fazendo é o seguinte, eu estou verificando se as execuções que eu passei para ele algum momento foram chamadas, por essa implementação, vou fazer uma pergunta para você: Se eu passar, se tiver uma execução que não estiver nessa lista que eu passei para ele. Imagina que eu passo uma lista com duas execuções e na verdade ele tem executado três, sendo que essas duas estão contidas nessas três. Ele vai dar algum problema? Responde aí. Não, ele não vai dar, porquê? Porque ele só verifica se as execuções estão contidas nas que eu passei para ele, então, se eu tiver alguma a mais a princípio ele não vai dar problema ou se eu chamar, se essas execuções forem chamadas numa ordem diferente também não vai dar problema. E aí se você falar não, mas eu quero que sejam chamadas exatamente aquelas, e exatamente na ordem que eu passar. Aí eu posso ir lá e criar por exemplo, método de verificação diferente. Então, nesse caso eu chamei de verifica sequência, então note que ele pega, ele vai do 1 até ao tamanho e aí ele varifica se aquela posição, do que foi executado é igual àquela posição do que eu passei para ele. Então, euu estou dando esse exemplo para mostrar que eu posso ter várias execuções diferentes, vários métodos que verificam a execução de uma forma diferente. Então eu posso ter que verifica sequencia, eu posso ter outro que verifica só se foi executado ou não, a ordem, isso tudo depende dos requisitos da sua classe. Nesse caso você não tem que chamar o VerificaSequencia só por que é desse jeito que ele realmente executa. Não, mas você tem que chamar o VerificaSequencia se existe requisito para a sua classe no qual aquela sequência é importante. Lembrando sempre quando a gente cria Mock, a gente tem que criar essas verificações de acordo com os requisitos da classe que a gente está criando, e não do jeito que ela realmente funciona. Porquê? Porque às vezes eu posso modificar essa classe de uma forma válida e às vezes ele trocar uma ordem ou alguma coisa na chamada e isso aí aí ela vai continuar correta mas o meu teste vai falhar, por quê? Porque eu amarrei demais a forma que eu disse que tinha que ser a execução da classe. Então vamos dar uma olhada no teste, como que ficaria teste, usando isso aí. Então note que eu, por exemplo, imagino que tem uma classe ali que cria ranking, né, pegando o gancho que o nosso projeto vai ser de gamification, o projeto aí de final de curso do programa de cursos integrados, então vamos pegar esse exemplo aqui que eu tenho que criar ranking e o que que eu vou fazer? Eu preciso dessa classe executor, então eu vou criar ExecMock e vou utilizar o método set, no caso eu estou usando dos tipos de injeção que a gente viu na aula anterior, estou usando aí a injeção de dependência para colocar o mock, aí eu chamo o método criar, que seria exatamente a funcionalidade si que eu quero verificar, que eu quero executar, e aí eu quero saber se essa classe, se esse criador ranking, chamou os métodos, se chamou o método executar, que ele deveria chamar, ali na classe na dependência, no ExecMock. Então eu chamaria o Mock.verifica, ali ordenar pontos, escolher ganhadores e mandar e-mail para os vencedores. Então eu vou estar verificando se todas essas execuções foram chamadas ali no mock. Bom, eu sei que você pode agora estar começando a ficar preocupado de que criar esses mocks, de acordo com a dependência que você precisar, se ela tiver vários métodos ou tiver várias possibilidades, ou receber vários parâmetros, isso aí pode ficar muito complicado. A realidade é que realmente pode ficar complicado. Dependendo do mock, ele pode, se ele tiver vários métodos, pode realmente ficar bem complicado estar criando esses mocks na mão. Felizmente, temos frameworks que funcionam como fábricas de mock, ou seja, você não precisa ir lá e criar uma classe, arquivo separado para o seu mock. Você pode no próprio método de teste, falar assim: olha, cria para mim mock dessa interface, que quando chamar o método tal, ele vai retornar tal coisa, e verifica se ele chamou esse cara uma vez com tal parâmetro. Então existem frameworks de mock que têm essa funcionalidade, facilitam bastante a vida, não está no escopo deste curso inicial aqui de TDD falar sobre esses frameworks, mas eu acho importante nesse momento dizer para você que esses frameworks existem e eu até aconselho que vocês procurem, eu já posso dar alguns nomes aqui como Jmock, o Easymock, o Mockito Java e outras linguagens também tem vários frameworks para criação de mock Object. Certo, então fica aí opcional para vocês fazerem essa pesquisa. Então espero que com isso, nessa aula, vocês tenham conseguido entender essas diretivas do mock object, como a gente viu são 3, uma delas você ter a mesma interface da dependência, a segunda você estar simulando o comportamento da classe, com retornos, exceções e etc; e terceiro estar verificando as chamadas feitas pela classe que está sendo testada. Certo, então vendo essas 3 diretivas a gente percebe qual que é o papel, quais os tipos de coisa o mock object pode fazer. Certo? Muito obrigado por assistir, até a próxima aula. [MÚSICA]