Mockowanie oparte na protokołach i wstrzykiwanie zależności
Wstrzykiwanie atrap testowych za pomocą protokołów bez zewnętrznych frameworków do mockowania.
Mockowanie oparte na protokołach i wstrzykiwanie zależności to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 3 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.
Po co mockowanie oparte na protokołach?
Używanie protokołów jako punktów podmiany umożliwia zastępowanie rzeczywistych implementacji atrapami testowymi bez modyfikowania kodu produkcyjnego.
protocol NetworkService {
func fetch(url: URL) async throws -> Data
}
class RealNetworkService: NetworkService { /* URLSession */ }
class MockNetworkService: NetworkService { /* returns fixtures */ }Definiowanie protokołu
Wyodrębnij protokół z zależności, umieszczając w nim tylko metody potrzebne klasie.
protocol UserRepository {
func getUser(id: Int) async throws -> User
func saveUser(_ user: User) async throws
}Wstrzykiwanie przez inicjalizator
Przekaż zależność przez inicjalizator, aby testy mogły dostarczyć mock.
class ProfileViewModel {
private let repo: UserRepository
init(repo: UserRepository = RealUserRepository()) {
self.repo = repo
}
}Pisanie mocka
Zaimplementuj protokół za pomocą kontrolowalnego stanu: rejestruj wywołania i zwracaj wartości zastępcze.
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 {}
}Zastępcze wartości zwracane
Skonfiguruj wartości zastępcze przed testem, aby kontrolować to, co zwraca mock, i symulować różne scenariusze.
let mock = MockUserRepo()
mock.stubbedUser = User(id: 42, name: "Alice")
let vm = ProfileViewModel(repo: mock)
await vm.loadProfile(id: 42)
XCTAssertEqual(vm.userName, "Alice")Weryfikowanie interakcji
Po wykonaniu operacji przez testowany system sprawdź, czy mock został wywołany z oczekiwanymi argumentami.
XCTAssertEqual(mock.fetchedIds, [42], "Should fetch user 42 exactly once")Symulowanie błędów
Zgłaszaj błędy z mocka, aby testować ścieżki obsługi błędów w kodzie produkcyjnym.
class FailingRepo: UserRepository {
func getUser(id: Int) async throws -> User { throw NetworkError.notFound }
func saveUser(_ user: User) async throws { throw NetworkError.serverError(500) }
}Wstrzykiwanie przez właściwość
Alternatywnie udostępnij zależność jako właściwość, której można przypisać nową wartość, aby uprościć jej zastępowanie w testach.
class OrderService {
var paymentGateway: PaymentGateway = StripeGateway()
}
let service = OrderService()
service.paymentGateway = MockPaymentGateway()Wstrzykiwanie @Environment / @EnvironmentObject
Aplikacje SwiftUI wstrzykują zależności przez środowisko, dzięki czemu można testować widoki, dostarczając mockowane obiekty środowiskowe.
let mockStore = MockCartStore()
let view = CartView().environmentObject(mockStore)Unikanie nadmiernego mockowania
Mockuj tylko bezpośrednie zależności; używaj rzeczywistych współpracujących obiektów, gdy ich działanie jest deterministyczne i szybkie.
// OK to use real DateFormatter in tests — it's deterministic
// Mock URLSession — network I/O is slow and non-deterministicKompozycja protokołów dla węższych interfejsów
Używaj mniejszych, wyspecjalizowanych protokołów (zasada segregacji interfejsów), aby mocki implementowały tylko to, co jest potrzebne.
protocol Readable { func read() async throws -> [Item] }
protocol Writable { func write(_ item: Item) async throws }
typealias ReadWrite = Readable & WritableSzybkie sprawdzenie
Jaka jest główna korzyść z wstrzykiwania zależności za pomocą protokołu zamiast konkretnego typu?
Podsumowanie lekcji
Zdefiniuj punkt podmiany oparty na protokole dla każdej zależności. Wstrzykuj zależności przez inicjalizator. Implementuj mocki, które rejestrują wywołania i zwracają wartości zastępcze. Symuluj błędy za pomocą mocków zgłaszających błędy. Weryfikuj interakcje za pomocą XCTAssertEqual na tablicach zarejestrowanych wywołań.
Często zadawane pytania
Czy lekcja „Mockowanie oparte na protokołach i wstrzykiwanie zależności” jest bezpłatna?
Tak — pełny tekst „Mockowanie oparte na protokołach i wstrzykiwanie zależności” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „Mockowanie oparte na protokołach i wstrzykiwanie zależności”?
Wstrzykiwanie atrap testowych za pomocą protokołów bez zewnętrznych frameworków do mockowania. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Swift Academy?
Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 3 z 4.
Ile czasu zajmuje lekcja „Mockowanie oparte na protokołach i wstrzykiwanie zależności”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?
Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- Konfiguracja XCTestCase, sprzątanie i metody testowe
- Rodzina XCTAssert i asercje zgłaszające błędy
- Mockowanie oparte na protokołach i wstrzykiwanie zależności
- Testy asynchroniczne i pomiar wydajności