Dagger Android, tudo que você precisa entender em português. Parte-2

Carlos
Android Dev BR
Published in
6 min readJul 21, 2020

E ai tudo bem? Dando sequência a parte 2 sobre Dagger Android, na primeira parte vimos os conceitos básicos que você precisa saber, antes de sair usando alguma ferramenta(Você encontra a primeira parte neste blog mesmo)

Então vamos lá ao nosso menu de guia

Os links de toda a sequência você encontra aqui:

______________________________________________________________

Parte 2 — Na segunda parte deste assunto iremos ver na prática como por exemplo:

  • Configurando um modulo como exemplo.
  • Exemplo de testes unitários deste modulo.
  • Exemplo de testes integrados com Espresso.
  • Vantagens
  • Desvantagens.
  • Outros Design Patterns parecidos.
  • Outras bibliotecas disponíveis.
  • Repositório onde você encontra todos os exemplos.

______________________________________________________________

Configurando o Dagger Android

Bom, vamos agora configurar então o Dagger e usar em nosso projeto.

Adicionando lá no Build.Gradle App

e dentro do dependencies

Em nosso Application, temos que criar lá a inicialização do Dagger.

O nome DaggerAppComponent é porque meu Dagger se chama AppComponent. Então é preciso criar essa classe.

É importante notar que este nosso AppComponent tem noção do Contexto geral da aplicação. Por isso fica fácil também injetar nossos modulos. O gráfico seria assim:

No nosso exemplo vamos criar um LoginComponent.

Vamos visualizar ele como um Sub-componente, pois ele poderá ser usado em diversos lugares a mesma instância dos objetos.

Para usar o Dagger, precisamos sempre falar para ele quem vai usar, no nosso caso a Activity vai precisar das futuras injeções.

E ai no nosso AppComponent, temos que dizer que este é um modulo a ser visto/injetado.

A visão do gráfico de dependências ficaria assim:

Para nosso exemplo, vamos criar então 3 modulos.

  • ViewModel
  • Repository
  • DataSource

No DaggerAndroidActivity, injetamos nosso viewmodel

Pronto. O exemplo esta funcionando.

A visualização do gráfico hoje de nossas dependências ficaria assim:

______________________________________________________________

Exemplo de testes unitários deste modulo

Agora vamos implementar como testar nosso viewmodel. O modo como é feito no Repository e Datasource segue a mesma regra. Logo, vamos apenas implementar como exemplo o viewmodel agora para fins didáticos.

Bom, primeiro temos que ter em mente sobre o InstantTaskExecutorRule

para caso tenhamos tasks ele consiga enxergar isso e não trave nosso teste.

Depois vamos adicionar ao nosso exemplo a biblioteca MocKK

Essa biblioteca é bem legal. Fácil de usar e testar. Deixei comentado em casos que você não precisa saber da resposta para auxiliar você no seus testes também.

Uma vez, vamos validar então na chamada do nosso viewModel quando fizer o doLogin, responder da maneira correta.

Para isso as configurações iniciais são:

Para validar então nosso teste, temos que dizer que o repository vai nos dar uma resposta de acordo com nosso cenário de testes.

E assim nossos UnitTest ficariam:

Nosso resultado:

______________________________________________________________

Exemplo de testes integrados com Espresso

Chegamos em um tópico que eu gosto muito, e foi um pouco não complicado mas difícil de enxergar a primeira vista.

Para primeiro partirmos de Dagger + Espresso. Temos que ter uma pre-configuração no nosso androidTest package.

E no nosso build.gradle App também. Essa é uma sacada que não tem gloria alguma saber, na verdade acho que isso que é o que “emperra” o pessoal na minha opinião quando vai pegar esse assunto.

Primeiro, você deve criar uma base para seus testes integrados.

Com um MyCustomTestRunner que estenda AndroidJUnitRunner. E esta implemente seu MyApplication mas no caso, de testes.

Ficaria assim:

Primeiro adicione que seu compilador de AndroidJUnitRunner é o seu MyCustomTestRunner no build.gradle App.

Lá dentro do defaultConfig

Aqui é importante acertar o caminho do seu CustomAndroidJUnitRunner para o seu teste integrado funcionar.

E seu MyTestApplication que vai injetar os modulos fakes de respostas ao devido comportamento que você deseja.

Reparem que eu coloquei em destaque que nesse meu modulo de TestAppComponent eu adiciono um RepositoryFakeModule.

Então assim quando eu iniciar o meu teste integrado. Ele vai me dar o cenário de resposta falsa.

Para terminar então nosso teste de aplicação ficaria assim:

Criei um Gif para você visualizar como funciona o teste.

E é isso, o resto é contigo. Se precisar vai mockando seus cenários nos testes integrados.

______________________________________________________________

Vantagens

Vamos lá, meus pontos de vistas sobre usar Dagger.

  • Java/Kotlin — Podemos usar tanto em projetos Java como Kotlin. Querendo ou não ainda muita gente escreve seus projetos em Java.
  • Reusabilidade de código
  • Fácil de testar
  • Manutenção do código se feito de maneira correta tende a ser melhor que uma injeção manual ou outros Design Patterns em minha visão.
  • Time do Google pretende colocar no Jetpacket. Isso é importante sim pois mostra que vão procurar dar suporte a essa lib.
  • Uma vez entendido o assunto, o stack de erros começa a fazer sentido.

______________________________________________________________

Desvantagens

Como tudo na vida, nada bom é fácil. Então ao meu ver essas são as dificuldades encontradas:

  • A curva de aprendizado sem uma documentação em dia se torna uma dor de cabeça, agora com o Hilt novo produto do Android tá ficando mais fácil nesse ponto.
  • Anotações de processos tendem a mudar e ai seu código pode vir a quebrar se não ao menos tiver um @Deprecated para te ajudar.
  • Realmente, a parte do Espresso não achei muitos exemplos, o único bom mesmo é o codelab lançado pela google aqui neste link: https://codelabs.developers.google.com/codelabs/android-dagger/index.html?index=..%2F..index#13
  • Existem outras libs que tendem a ter uma configuração menos complexa ao que parece: Koin é uma delas. Kodein não cheguei a implementar no momento que escrevo esta artigo.
  • É necessário ter essa visualização de gráfico de dependências que ainda não é visível o que causa um certo desconforto mental no meu ver. Já vi libs que estão planejando atender a essa necessidade.

______________________________________________________________

Outros Design Patterns parecidos

Bom, como existem vários outros tipos de Design Patterns parecidos é interessante saber a diferença e como justificar sua resposta em usar ou não DI.

São eles:

  • Singleton
  • ServiceLocator

______________________________________________________________

Singleton:

Singleton é uma instância viva que vai ficar viva enquanto seu app esta funcionando. O que pode deixar ele devagar (Acúmulos de Singletons onde não precisa). Dependência de injeção temos o controle do que é uma fábrica para certos componentes, quando precisamos renovar essas fábricas e quando queremos uma única instância viva dessa classe sim com Singleton Pattern.

Para saber mais segue referências:

https://pt.wikipedia.org/wiki/Singleton

______________________________________________________________

ServiceLocator

Service Locator, também um Design Pattern e tem o problema de uma classe ficar “inchada” com muitos objetos vivos e no fim sua classe de modulo vai ver mais do que precisa. Além das constantes repetições de tipos diferentes vivas como no exemplo Ferrari, Mereces. DI é uma injeção externa, eu digo lá na config que para aquele caso vou precisar disso, disso e acabou.

Para saber mais segue referências:

https://en.wikipedia.org/wiki/Service_locator_pattern

______________________________________________________________

Outras bibliotecas disponíveis

Bom, como dito acima, existem algumas outras bibliotecas. As que eu destaco mais nesse momento seria o Koin. Mas temos também o Kodein. Segue sites deles para mais detalhes.

Link Koin:

https://doc.insert-koin.io/

Link Kodein:

https://kodein.org/Kodein-DI/?6.5/core

______________________________________________________________

Repositório onde você encontra todos os exemplos

Bom, é isso por essa parte, na próxima vou mostrar como usar isso em um projeto modularizado.

Espero que você tenha gostado, deixa seu joinha ai e vamos para o próximo passo! Valeu, abraço.

--

--