Mockowanie zależności w testach
Zastępowanie rzeczywistych implementacji atrapami testowymi.
Mockowanie zależności w testach to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 4 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.
Mockowanie zależności w testach
Mock to fikcyjna implementacja zależności używana w testach. Ponieważ wstrzykujemy protokoły, możemy dostarczyć mock zamiast prawdziwego obiektu współpracującego.
Protokół do zamockowania
Należy zacząć od protokołu opisującego zależność. Zarówno prawdziwy typ, jak i mock są z nim zgodne.
protocol UserStore {
func name(for id: Int) -> String
}
struct RealStore: UserStore {
func name(for id: Int) -> String { "User-\(id)" }
}
print(RealStore().name(for: 5))Pisanie mocka
Mock jest zgodny z protokołem, ale zwraca ustalone wartości, dzięki czemu nie trzeba korzystać z prawdziwego dostępu do sieci ani dysku.
protocol UserStore { func name(for id: Int) -> String }
struct MockStore: UserStore {
func name(for id: Int) -> String { "Mock" }
}
print(MockStore().name(for: 99))Wstrzykiwanie mocka
Należy przekazać mock do testowanego systemu za pomocą jego inicjalizatora. Testowany kod nie może odróżnić go od prawdziwej zależności.
protocol UserStore { func name(for id: Int) -> String }
struct MockStore: UserStore { func name(for id: Int) -> String { "Mock" } }
struct Profile {
let store: UserStore
func title(_ id: Int) -> String { "Hello, " + store.name(for: id) }
}
print(Profile(store: MockStore()).title(1))Rejestrowanie wywołań
Mock może rejestrować sposób użycia, dzięki czemu test może sprawdzić, czy zależność została wywołana prawidłowo.
protocol Analytics { func track(_ e: String) }
class SpyAnalytics: Analytics {
var events: [String] = []
func track(_ e: String) { events.append(e) }
}
let spy = SpyAnalytics()
spy.track("open")
spy.track("buy")
print(spy.events)Sprawdzanie zachowania
Po wykonaniu kodu należy sprawdzić zarejestrowane dane. W tym przypadku weryfikujemy, czy został uruchomiony właściwy event.
protocol Analytics { func track(_ e: String) }
class Spy: Analytics { var last = ""; func track(_ e: String) { last = e } }
struct Checkout { let analytics: Analytics; func pay() { analytics.track("paid") } }
let spy = Spy()
Checkout(analytics: spy).pay()
print(spy.last == "paid")Podstawianie wartości zwracanych
Stub zwraca ustalone wcześniej wartości, dzięki czemu można sprawdzić, jak kod reaguje na konkretne dane wejściowe.
protocol Clock { func hour() -> Int }
struct StubClock: Clock { let value: Int; func hour() -> Int { value } }
struct Greeter { let clock: Clock; func greet() -> String { clock.hour() < 12 ? "AM" : "PM" } }
print(Greeter(clock: StubClock(value: 9)).greet())
print(Greeter(clock: StubClock(value: 18)).greet())Symulowanie błędów
Mocki mogą symulować warunki błędów, które trudno wywołać w przypadku prawdziwych zależności, zwiększając pokrycie testami.
protocol Loader { func load() -> Int? }
struct FailingLoader: Loader { func load() -> Int? { nil } }
struct VM { let loader: Loader; func status() -> String { loader.load() == nil ? "error" : "ok" } }
print(VM(loader: FailingLoader()).status())Deterministyczne testy
Ponieważ mocki zwracają stałe wartości, testy są szybkie i deterministyczne, bez niestabilności powodowanej przez prawdziwe usługi.
protocol Random { func next() -> Int }
struct FixedRandom: Random { func next() -> Int { 42 } }
struct Game { let rng: Random; func roll() -> Int { rng.next() } }
print(Game(rng: FixedRandom()).roll())Bez frameworka testowego
W prawdziwym projekcie te sprawdzenia byłyby zapisane za pomocą asercji XCTest. Wzorzec wstrzykiwania pozostaje taki sam, zmienia się tylko składnia asercji.
protocol Calc { func add(_ a: Int, _ b: Int) -> Int }
struct RealCalc: Calc { func add(_ a: Int, _ b: Int) -> Int { a + b } }
struct MockCalc: Calc { func add(_ a: Int, _ b: Int) -> Int { 0 } }
print(RealCalc().add(2, 2))
print(MockCalc().add(2, 2))Pełny przebieg
Należy zdefiniować protokół, napisać zgodne z nim implementacje prawdziwą i mock, wstrzyknąć mocka, wykonać kod i sprawdzić wynik. DI umożliwia każdy z tych kroków.
protocol Repo { func count() -> Int }
struct MockRepo: Repo { func count() -> Int { 3 } }
struct Stats { let repo: Repo; func total() -> Int { repo.count() * 2 } }
print(Stats(repo: MockRepo()).total())Szybki test
Co w tym podejściu umożliwia mockowanie zależności?
Podsumowanie
Mock jest zgodny ze wstrzykiwanym protokołem i zwraca ustalone wartości, rejestruje wywołania lub symuluje błędy. Jego wstrzyknięcie pozwala tworzyć szybkie i deterministyczne testy. Przebieg jest następujący: zdefiniować protokół, napisać zgodne z nim implementacje prawdziwą i mock, wstrzyknąć zależność, wykonać kod i sprawdzić wynik. To kończy kurs DI.
Ucz się Swift dzięki korepetycjom AI — za darmo
Pisz i uruchamiaj kod w przeglądarce, otrzymuj natychmiastową pomoc od korepetytora AI dostępnego 24/7 i kontynuuj naukę w sieci lub w aplikacji.
- Kursy
- 122
- Lekcje
- 409
Często zadawane pytania
Czy lekcja „Mockowanie zależności w testach” jest bezpłatna?
Tak — pełny tekst „Mockowanie zależności w testach” 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 zależności w testach”?
Zastępowanie rzeczywistych implementacji atrapami testowymi. Ć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 4 z 4.
Ile czasu zajmuje lekcja „Mockowanie zależności w testach”?
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
- Dlaczego warto stosować dependency injection
- Wstrzykiwanie przez konstruktor
- Abstrakcje oparte na protokołach
- Mockowanie zależności w testach