0Pricing
Swift Academy · Lektion

Protokollbasiertes Mocking und Dependency Injection

Schleusen Sie Test-Doubles über Protokolle ein, ohne Mocking-Frameworks von Drittanbietern.

Protokollbasiertes Mocking und Dependency Injection ist eine kostenlose Swift Academy-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des Swift Academy-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der Swift Academy-Kurs umfasst insgesamt 4 Lektionen.

Warum Mocking auf Protokollbasis?

Protokolle als Nahtstellen ermöglichen es, echte Implementierungen durch Test-Doubles zu ersetzen, ohne den Produktionscode zu ändern.

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

Das Protokoll definieren

Leiten Sie aus Ihrer Abhängigkeit ein Protokoll ab, das nur die von Ihrer Klasse benötigten Methoden enthält.

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

Über den Initializer injizieren

Übergeben Sie die Abhängigkeit über den Initializer, damit Tests einen Mock bereitstellen können.

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

Einen Mock schreiben

Implementieren Sie das Protokoll mit steuerbarem Zustand: Protokollieren Sie Aufrufe und geben Sie Stub-Werte zurück.

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 {}
}

Rückgabewerte von Stubs

Konfigurieren Sie Stubs vor dem Test, um die Rückgabewerte des Mocks zu steuern und verschiedene Szenarien zu simulieren.

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

Interaktionen überprüfen

Überprüfen Sie nach der Ausführung des zu testenden Systems mit einer Assertion, dass der Mock mit den erwarteten Argumenten aufgerufen wurde.

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

Fehler simulieren

Lassen Sie den Mock Fehler auslösen, um Fehlerbehandlungspfade im Produktionscode zu testen.

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

Eigenschaftsinjektion

Alternativ können Sie die Abhängigkeit als setzbare Eigenschaft bereitstellen, um sie in Tests einfacher zu ersetzen.

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

@Environment / @EnvironmentObject-Injektion

SwiftUI-Apps injizieren Abhängigkeiten über die Umgebung. Dadurch können Ansichten getestet werden, indem Mock-Umgebungsobjekte bereitgestellt werden.

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

Übermäßiges Mocking vermeiden

Mocken Sie nur direkte Abhängigkeiten. Verwenden Sie echte Mitwirkende, wenn diese deterministisch und schnell sind.

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

Protokollkomposition für engere Schnittstellen

Verwenden Sie kleinere, fokussierte Protokolle (Interface Segregation Principle), damit Mocks nur das Notwendige implementieren müssen.

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

Kurze Überprüfung

Was ist der wichtigste Vorteil, Abhängigkeiten über ein Protokoll statt über einen konkreten Typ zu injizieren?

Zusammenfassung der Lektion

Definieren Sie für jede Abhängigkeit eine Protokoll-Nahtstelle. Injizieren Sie sie über den Initializer. Implementieren Sie Mocks, die Aufrufe protokollieren und Stubs zurückgeben. Simulieren Sie Fehler mit fehlerwerfenden Mocks. Überprüfen Sie Interaktionen mit XCTAssertEqual für die Arrays der aufgezeichneten Aufrufe.

Häufig gestellte Fragen

Ist die Lektion „Protokollbasiertes Mocking und Dependency Injection“ kostenlos?

Ja — der vollständige Text von „Protokollbasiertes Mocking und Dependency Injection“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des Swift Academy-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der Swift Academy-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Protokollbasiertes Mocking und Dependency Injection“?

Schleusen Sie Test-Doubles über Protokolle ein, ohne Mocking-Frameworks von Drittanbietern. Du übst Swift Academy mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um Swift Academy zu starten?

Keine Vorkenntnisse erforderlich. Swift Academy auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Protokollbasiertes Mocking und Dependency Injection“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser Swift Academy-Lektion Code schreiben und ausführen?

Ja. Jede Swift Academy-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. XCTestCase: Setup, Teardown und Testmethoden
  2. Die XCTAssert-Familie und auslösende Assertions
  3. Protokollbasiertes Mocking und Dependency Injection
  4. Asynchrone Tests und Leistungsmessung
← Zurück zu Swift Academy