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-deterministicProtokollkomposition 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 & WritableKurze Ü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
- XCTestCase: Setup, Teardown und Testmethoden
- Die XCTAssert-Familie und auslösende Assertions
- Protokollbasiertes Mocking und Dependency Injection
- Asynchrone Tests und Leistungsmessung