Olá, sejam todos muito bem-vindos a mais uma aula. E na hora de hoje, a gente vai entender como fazer os nossos casos de uso trabalharem dentro do contexto de ingestão de dependência, do contexto de imersão de controle do Spring, sem fazer com que eles fiquem acoplados ao framework, ao Spring. Existem duas formas muito bacaninhas de ser utilizado, e eu deixo para você escolher, e depois eu falo um pouquinho de como a gente usa aqui no Mercado Livre, e como eu acho que poderia ser usado, e como eu acho que... Usem a approach, na verdade tem mais de uma abordagem. Eu vou mostrar todos para vocês. Então, vamos lá. Se a gente fosse fazer os testes integrados aqui do nosso caso de username, o que a gente poderia fazer? Como está tudo aqui na mesma pasta, a gente poderia só brincar com a nomenclatura dos nomes. Depois a gente aprende a como separar melhor. Mas, por enquanto, a gente pode brincar com a nomenclatura dos nomes. Depois a gente aprende a como separar melhor. Mas por enquanto a gente pode brincar com a nomenclatura dos nomes. Então, createCustomerUseCaseIT. Ou seja, integrationTest. É um dos padrões também utilizados. O que a gente faria aqui? Arroba Spring BootTest. Como a gente não tem nenhuma classe de configuração não precisa passar nada, active profiles test para testar do jeito que está a gente basicamente importaria aqui o customer service com o auto irid e aí seria importante um, na verdade um void before each ou melhor a gente pode usar até o teardown vamos padronizar o teardown aqui porque a gente pode usar o after each customer opa, customer service ponto, ah não tem delete all aqui então a gente precisaria do customer repository, olha como uma coisa vai levando a outra né a gente precisaria do customer repository pra fazer o delete all limpamos a base pra garantir que não tem nenhuma afetação de algum outro teste e aí aqui basicamente é vala e aqui também findbyid, empty, empty, isso aqui é vala, isso aqui é vala também na verdade tudo que é moquito aqui é valo no cliente principalmente nesse aqui não deve cadastrar o cliente com cps duplicado esse aqui já não é vala né quer dizer aqui é vala aqui aqui é vala só que a gente precisaria passar pelo save do e-customer aqui e é esse id é vala então a gente tem aqui o customer na verdade nem utiliza ele então ok isso aqui e a gente até isso aqui a gente fala que retorna isso aqui cpf e mail e final name então esse metodozinho útil, vamos colocar aqui embaixo createCustomer cpf email name beleza, esse cara aqui a gente até pode mover pra cima, antes do createInput, aqui a gente até pode mover pra cima né antes do do create input aqui a mesma coisa e aí um pro outro muda que esse é o email e esse é o cpf então o cpf tem que ser diferente né pra não conflitar beleza é... cadê cadê diferente na verdade esse aqui ó o e-mail aqui teste create duplicate e-mail should fail esse vai ser o que a gente vai passar mas na verdade a gente vai usar algum outro para persistir anteriormente então para não conflitar o cpf e esse aqui não tem problema que já passar mesmo duas vezes aqui vala não tem mais mock e aí vamos rodar o teste para ver rodando o teste beleza o teste passou integradão ao framework ele é um narrow, um teste integrado pequeno, porque ele só testa o nosso service, não tem um escopo tão amplo, mas é um teste integrado porque depende do framework. Beleza. Essa é a abordagem número 1. A gente instanciou aqui dentro o CreateCustomer porque ele ainda não é um bin gerenciado do Spring. Então a gente está instanciando aqui dentro. Mas como fazer para que ele seja um bin do Spring, para que a gente não precise instanciá-lo e sim consiga utilizar a inversão de controle do Spring da injeção de dependência dele para trabalhar então a gente pode fazer de duas formas na verdade de três de três formas a primeira é vir aqui no Create Customer do jeito que está e meter um arroba service dessa forma do jeito que está, e meter um arroba service. Dessa forma, a gente já coplou o nosso caso de uso ao framework. O hexagonal fala alguma coisa sobre isso? Não, ele não fala nada sobre isso. Poderíamos seguir dessa forma? Poderíamos seguir dessa forma? Poderíamos seguir dessa forma Diferente do Clean Architecture Que o autor prega muito Sobre você separar o core Da sua aplicação de framework No hexagonal Não tem tanto essa pegada No hexagonal o foco É outro E é um foco mais direto Na entrada e na saída dos seus casos de uso E não se está muito Acoplado ao framework, etc um foco mais direto na entrada e na saída dos seus casos de uso, e não se está muito acoplado ao framework, etc. Mas o que a gente pode fazer então? Ao invés de fazer acoplado ao framework, também tem a opção de utilizar o Javax API, que na verdade é a APIi de cdi do java a gente poderia vir aqui e incluir se eu não me engano vamos ver se eu sei de cabeça javax.inject era isso bom vamos ter que dar uma googlada Porque agora fugiu de cabeça Não vou lembrar Javax Injection Versão 1 Javax Injection Javax Injection Javax Injection Isso aqui foi a primeira versão Das annotations Da especificação de CDI do Java Só que a gente só precisa da Annotation Inject aqui Na verdade nem é Inject, Inject é no Controller É Annotation Named Com essa Annotation Named, a gente não fica culpado mais ao framework com essa notation named a gente não fica acoplado mais ao framework porque isso aqui é da especificação do java tudo bem que o javax já foi deprecado e inclusive talvez nem seja de fato essa que o spring reconhece nessa versão 3 porque eu acho que ele já está integrado ao jacarta e não mais o javax mas é uma maneira de fazer de fazer isso funcionar sem que você fique ac integrado ao jakarta e não mais o javax. Mas é uma maneira de fazer isso funcionar sem que você fique cobrado ao framework. É só ver qual é a... deixa eu ver aqui... jakarta inject API e já que se piar talvez essa que funciona já carlton já já que talvez essa que funciona na verdade a gente até pode testar vamos lá vamos testar eu vou copiar isso aqui a gente traz para cá aqui no mercado livre vai doer a gente usa do jacar do java que aqui, ainda está nessa versão antiga, dessa forma como estou mostrando para vocês. É a forma que eu gosto e que eu mais aconselho? Não é. Eu particularmente gosto de fazer as instâncias na mão e declarar na mão esse cara. Mas, ok, vamos me relevar. um colocar aqui a versão certa cara existe agora é o neymar do jacarta beleza se a gente vier nosso teste aqui agora por exemplo a gente não precisa, private, create customer, create customer, use case, auto-lighted, vamos colocar só como use case aqui, vai, use case, isso aqui vai para a vala, isso aqui vai para a vala, isso aqui vai para a vala, e aqui a gente pode usar o repository direto, não tem problema. Vamos ver, vamos rodar o teste. Pra ver se vai funcionar, pra ver se passa. Porque eu tô acostumado com o javax lá, só que depois... Ó, funcionou. Ou seja, injetou o nosso caso de uso. A gente conseguiu declarar um bin do Spring, utilizando uma especificação da JDK, da Jakarta, na verdade, que não é a culpa da framework nenhum e que todos os frameworks na verdade reconhecem essa especificação porque é a especificação oficial então o Spring consegue entender as annotations do Jakarta, o Quarkus consegue entender, o Micronaut consegue entender, todos eles que tem uma o Quarkus na verdade utiliza a especificação por debaixo dos panos do Jakarta. Então, todos eles vão conseguir entender. Mas, qual que é a terceira forma que eu estou falando para vocês? A terceira forma é declarar na mão. Vamos criar aqui, então, um pacote com... Na verdade, já vamos fazer isso da forma correta. Vamos criar um pacote chamado InfraStructure Depois a gente vai mover tudo pra lá E aí a gente vai Criar então o nosso Vamos fazer o seguinte, vamos mover o main pra lá Já, que ele vai pra lá depois E vai E já permite que eu não tenha um conflito de pacotes Aqui, conflito de pacotes não Que o pacote um não nest no outro. E vamos criar aqui, configurations. E a gente vai colocar aqui, useCase config. arroba configuration e a gente vai declarar aqui ó public create customer use case create customer use case return new create customer e aí arroba bin e aí a gente pode colocar aqui ó private final customer service Porque esse cara vai ser usado várias vezes Por vários casos de uso E a gente passa aqui pra ele E belezinha Se a gente for lá no nosso teste Rodar de novo Ele vai funcionar também Opa, cadê? Unable to find Spring Boot Ah tá É porque o main tá ali dentro agora também, opa, cadê? unable to find Spring Boot ah tá é porque o main tá tá ali dentro agora, então vamos lá classes main.class beleza, então se a gente agora rodar opa o que que ele não encontrou use case config required Beleza, então se a gente agora rodar... Opa, o que ele não encontrou? Use case config required, customer service that could not been found. Deixa eu ver... Customer service... Ah tá, é porque como eu movi o main pra cá ele perdeu a referência dos packages que é pra escambia e fax então vamos colocar aqui o beijo da que raiz e não dentro de um frasco e como a gente não moveu as coisas pra dentro de infrastructure o ECD failed to load application context failed to load application context no qualify bin customer repositories vamos fazer o seguinte vamos mover tudo pra dentro de infrastructure beleza agora sim agora ainda pode remover isso aqui ó vamos lá rodando teste novamente é que o teste classe nem agora ele foi agora ele foi ok Agora ele foi. Ok. A gente já deixa até bonito, bem feito assim, que é o que a gente ia fazer mesmo. Então, essas são as três formas da gente conseguir pegar o nosso caso de uso, converter para um BIM do Spring e utilizar a injeção de dependência do Spring, a inversão de controle, a nosso favor. Dessa terceira maneira, a gente não gera nenhum acoplamento no nosso caso de uso com nenhuma anotação extra. É puro e simplesmente um pojo, um objeto. Não tem magia nenhuma. A gente está declarando a magia fora, aqui através do bing que é o approach que eu mais gosto de seguir tá e é por esse approach que a gente vai seguir daqui pra frente e como a gente já começou né vamos vamos fazer por os outros que vocês acham o cliente e 20 e ter cadê cadê cadê isso aqui a gente vai injetar aqui ó o pai private use case ficar a gente injeta a gente vai precisar mocar o partner e aqui que a gente colocar o evento né beleza então vamos lá private partner repository e o private event repository a gente vai precisar desses dois dois caras aqui aqui a gente vai void tear down pra deletar tudo before each part of repository .delete all event repository delete all e aí só pra ficar aqui na ordem bonitinho beleza esses dois caras já não precisa mais o mock aqui e nem o save não precisa de mais isso aqui também não precisa mais o que vai precisar mocar o mocar o partner então vamos criar aqui embaixo um teste private partner create partner aqui a gente vai partner vamos ver se não tem algum lugar que a gente já está mocando o partner de alguma forma não não não, getPartner por id, aqui a gente com certeza tá beleza, o id não vamos precisar, isso aqui a gente pode receber por parâmetros então string cnpj, string email, string name. cnpj, name, email, return partner repository, ponto save a partner. Beleza, então já estamos aqui criando um partner aqui a gente vai colocar um partner então vamos lá quem que a gente quer cnpj vou deixar 123 mesmo ou não vamos lá vamos pegar o cnpj bonitinho e o nome bonitinho opa e-mail e nome então beleza estamos locando o partner aí ele vai conseguir criar um evento ali não deve entrar enquanto o partner não for encontrado então isso aqui a gente não vai mocar partner. Não precisamos disso, não precisamos disso. Ele, por padrão, já vai dar erro para a gente. Então, ah tá, claro. A gente não tem, não fizemos a configuração. Então, vamos lá. Ah, como a gente já fez a configuração aqui, a gente até pode reaproveitá-la aqui fora. Então vou criar um cara aqui, um out insert, vamos criar uma interface, ou melhor, vamos criar uma classe, integration test, e a gente já coloca ela aqui Define ela como abstrata Para ela ser usada em todas As classes Que tem testes integrados Eu normalmente gosto de fazer isso via Annotation Mas como o curso não é focado na linguagem Java, lá no MBA, no curso Full Cycle, tem uma trajetória mais focada nisso. Lá eu ensino de outras maneiras, mas aqui o importante é o domínio. Então, vamos lá. O que ele quebrou aqui? Enable... então como a que que ele quebrou aqui ó o ney do atá como mude vai aqui pra dentro o main test vai aqui pra dentro também mais infrastructure, o integration pode ficar lá fora beleza, vamos rodar de novo e vamos ver o que ele vai reclamar passaram, passaram, passaram vamos só ver ah tá, esse aqui claro que ainda quebrou porque a gente ainda não declarou o caso de uso, né, então agora a gente vai lá em configurations, public, create event, use case, create event, new E aí ele demanda o Partner Service e demanda o Event Service. E aí Event Service para cá, um para lá, dois para cá. Vamos colocá-los aqui no nosso controller. A gente até pode quebrar porque está começando a ficar muita dependência aqui o object require no nulo o objeto expõe quais não lula agora a gente já tem ele aqui então a gente passa e vence o parque pra cá e declara como um bim agora sim a gente tem ele agora a gente pode até rodar aqui como um test e a gente vai ter bonito e bem feito o nosso teste integrado, opa, partner not found, test create create partner, ah claro não é que o partner not found, não é o PartnerNotFound Não é esse o PartnerIG Vamos mover aqui pra cima E FinalvarPartner Partner E aí o PartnerIG é na verdade isso aqui Agora sim É isso, show de bola Então a gente já tem dois Positivos aqui E agora vamos fazer A gente vai fazer um Positivo aqui aqui né, agora sim. É isso, show de bola. Então a gente já tem dois testes integrados funcionando perfeitamente, agora eu deixo para vocês fazerem os outros testes integrados, mas vamos fazer junto aqui as configurações dos outros casos de uso, né? Vamos deixar eles todos utilizáveis. Então, create event já foi, create partner agora, né? Já tá até fácil de fazer o create partner aqui. create partner importar, return new, create partner, porque a gente já tem o partner service aqui, né? Então, bin get customer public get customer by id, também então bem é de atingir o som é public de atingir o som é vai aí de também tá fácil agora que a gente já tem o o custo mais certo acho que eu já serve a gente já tem aqui né guete partner public de atingir o partner vai aí de return you get partner by a partir serve sim e um subscribe então public subscribe to event use case return news subscribe a ele Return new, subscribe, aí ele precisa do customer e do event. Show de bola. E aí o que dá pra gente fazer também? Agora que isso aqui tudo já é bin, a gente não precisa fazer aquilo que a gente tava fazendo nos controllers mais. Então vamos lá corrigir também? Customer, ó, aqui a gente precisa, a gente não precisa mais do service. A gente pode injetar o createCustomer direto. Ou melhor, vamos fazer isso na próxima aula, que a gente corrige aqui, usa as layers de adapters, estamos muito apressados, a gente corrige essas layers aqui na próxima aula. Nessa aula, a gente aprendeu a expor os nossos casos de uso via injeção de dependência lá do container do Spring e aprendemos também como fazer uns testes integrados nossos casos de uso via indição de dependência lá do container do Spring e aprendemos também como fazer uns testes integrados dos casos de uso. Então, é muito legal. Esses outros casos de uso deixo para vocês fazerem os testes integrados. Vamos ver se vai dar tudo certo. E espero que vocês tenham gostado. Vejo vocês na próxima aula.