0Pricing
Swift Academy · Aula

Mocking baseado em protocolos e injeção de dependências

Injete objetos de teste por meio de protocolos sem frameworks de mocking de terceiros.

Mocking baseado em protocolos e injeção de dependências é uma aula grátis de Swift Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Swift Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Swift Academy inclui 4 aulas no total.

Por que usar simulações baseadas em protocolos?

Usar protocolos como pontos de substituição permite trocar implementações reais por dublês de teste sem modificar o código de produção.

protocol NetworkService {
  func fetch(url: URL) async throws -> Data
}
class RealNetworkService: NetworkService { /* URLSession */ }
class MockNetworkService: NetworkService { /* returns fixtures */ }

Definindo o protocolo

Extraia um protocolo da sua dependência contendo apenas os métodos necessários para a sua classe.

protocol UserRepository {
  func getUser(id: Int) async throws -> User
  func saveUser(_ user: User) async throws
}

Injeção pelo inicializador

Passe a dependência pelo inicializador para que os testes possam fornecer uma simulação.

class ProfileViewModel {
  private let repo: UserRepository
  init(repo: UserRepository = RealUserRepository()) {
    self.repo = repo
  }
}

Escrevendo uma simulação

Implemente o protocolo com um estado controlável: registre as chamadas e retorne valores simulados.

class MockUserRepo: UserRepository {
  var fetchedIds: [Int] = []
  var stubbedUser: User = User(id: 1, name: "Test")
  func getUser(id: Int) async throws -> User {
    fetchedIds.append(id)
    return stubbedUser
  }
  func saveUser(_ user: User) async throws {}
}

Valores de retorno simulados

Configure os valores simulados antes do teste para controlar o que a simulação retorna e reproduzir diferentes cenários.

let mock = MockUserRepo()
mock.stubbedUser = User(id: 42, name: "Alice")
let vm = ProfileViewModel(repo: mock)
await vm.loadProfile(id: 42)
XCTAssertEqual(vm.userName, "Alice")

Verificando interações

Depois de exercitar o sistema em teste, verifique se a simulação foi chamada com os argumentos esperados.

XCTAssertEqual(mock.fetchedIds, [42], "Should fetch user 42 exactly once")

Simulação de erros

Lance erros a partir da simulação para testar os caminhos de tratamento de erros no código de produção.

class FailingRepo: UserRepository {
  func getUser(id: Int) async throws -> User { throw NetworkError.notFound }
  func saveUser(_ user: User) async throws { throw NetworkError.serverError(500) }
}

Injeção por propriedade

Como alternativa, exponha a dependência como uma propriedade configurável para facilitar sua substituição nos testes.

class OrderService {
  var paymentGateway: PaymentGateway = StripeGateway()
}
let service = OrderService()
service.paymentGateway = MockPaymentGateway()

Injeção de @Environment / @EnvironmentObject

Os apps SwiftUI injetam dependências pelo ambiente, permitindo testar as visualizações ao fornecer objetos de ambiente simulados.

let mockStore = MockCartStore()
let view = CartView().environmentObject(mockStore)

Evitando simulações excessivas

Simule apenas as dependências diretas; use colaboradores reais quando forem determinísticos e rápidos.

// OK to use real DateFormatter in tests — it's deterministic
// Mock URLSession — network I/O is slow and non-deterministic

Composição de protocolos para interfaces mais restritas

Use protocolos menores e focados (Princípio da Segregação de Interfaces) para que as simulações implementem apenas o necessário.

protocol Readable { func read() async throws -> [Item] }
protocol Writable { func write(_ item: Item) async throws }
typealias ReadWrite = Readable & Writable

Verificação rápida

Qual é o principal benefício de injetar dependências por meio de um protocolo em vez de um tipo concreto?

Recapitulação da lição

Defina um ponto de substituição baseado em protocolo para cada dependência. Injete-o pelo inicializador. Implemente simulações que registrem chamadas e retornem valores simulados. Simule erros com simulações que lançam erros. Verifique as interações com XCTAssertEqual nos vetores de chamadas registradas.

Perguntas Frequentes

A aula “Mocking baseado em protocolos e injeção de dependências” é grátis?

Sim — o texto completo de “Mocking baseado em protocolos e injeção de dependências” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Swift Academy, atualize para CoddyKit PRO. O curso de Swift Academy inclui 4 aulas no total.

O que vou aprender em “Mocking baseado em protocolos e injeção de dependências”?

Injete objetos de teste por meio de protocolos sem frameworks de mocking de terceiros. Você pratica Swift Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Swift Academy?

Nenhuma experiência prévia é necessária. Swift Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Mocking baseado em protocolos e injeção de dependências”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Swift Academy?

Sim. Cada aula de Swift Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Configuração, desmontagem e métodos de teste do XCTestCase
  2. Família XCTAssert e asserções que lançam erros
  3. Mocking baseado em protocolos e injeção de dependências
  4. Testes assíncronos e medição de desempenho
← Voltar para Swift Academy