Swift Academy · Lekcja

Mockowanie zależności w testach

Zastępowanie rzeczywistych implementacji atrapami testowymi.

Lekcja 4 z 413 kroki

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.

Bezpłatny start

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

  1. Dlaczego warto stosować dependency injection
  2. Wstrzykiwanie przez konstruktor
  3. Abstrakcje oparte na protokołach
  4. Mockowanie zależności w testach
← Powrót do Swift Academy