Oi!

Esse é o segundo de uma série de posts sobre testabilidade de código. Você pode encontrar o primeiro post da série aqui e ler mais sobre os conceitos básicos, estruturação e tipos de teste. Tem também esse outro post com links interessantes pra aprofundar os estudos.

Hoje vamos entrar mais em detalhes em uma das técnicas de programação que ajuda MUITO na hora de testar uma classe. Caro leitor, lhe apresento a injeção de dependência. E para descrever esse conceito vou usar a citação de James Shore:

“Dependency injection means giving an object its instance variables. Really. That’s it.”​

Mas o que isso significa Yasmin?? Ao invés de rodear você com teoria, vamos entender de maneira prática.

Um ViewController precisa realizar uma chamada à API para recuperar informações que serão apresentadas na tela. (Eu sei que essa chamada não deveria estar no view controller, mas vamos chegar na separação de responsabilidades nos próximos posts). Da maneira mais fácil, o próprio view controller inicializa sua instância de apiClient, classe responsável pelos requests http.

https://gist.github.com/453ca7cc5b0969e09d47ca090b1ebc5d

Como testar esse código que está fortemente acoplado ao view controller? O primeiro passo é remover a inicialização de dentro da classe e receber o apiClient no init da classe.

https://gist.github.com/407e62c0aa6ff619930eafb794660851

Ao fazer isso podemos passar a instância que desejarmos para o view controller. No entanto, APIClient ainda é uma classe concreta e esse não é o código mais testável que podemos alcançar. Damos então mais um passo e implementamos um protocolo APIClientProtocol que possui a declaração dos mesmos métodos que tínhamos em APIClient (esses métodos variam de acordo com a necessidade do seu projeto). Nossa classe APIClient conforma com o protocolo e implementa os métodos.

https://gist.github.com/b966fa9aec23178f8ef955106a13b972

Por fim, alteramos o init e a propriedade de MyViewController para receber como parâmetro uma instância de APIClientProtocol e não mais uma classe concreta. Durante o desenvolvimento, passaremos uma instância da classe APIClient no init do view controller.

https://gist.github.com/db58fe959d322d0b617b5468471e4108

Durante os testes, criaremos uma nova classe MockAPIClient, onde não precisaremos implementar toda a lógica de realmente chamar o server, parsear os dados recebidos e etc. Podemos apenas retornar uma completion vazia ou validar um booleano, por exemplo. Veremos esse teste em mais detalhes nos próximos posts.

O mais importante aqui é entender que o intuito é ter diferentes classes que implementam o mesmo protocolo, assim conseguimos trocar a classe passada para o view controller através da injeção de dependências.

https://gist.github.com/8030adfabbbb61576dd0e506c09a6be2

Easy peasy, right?!

Algo simples assim pode te ajudar — e muito — a aumentar a cobertura de testes do seu projeto e é um bom ponto de partida caso você esteja começando agora. No próximo post vamos dar uma olhadinha na arquitetura CleanSwift e depois teremos um exemplo prático, onde usaremos todos os conceitos do post anterior e desse. Não deixa de voltar pra ler, combinado?!?

Cheers!