Swift Academy · Lektion

Mocking af afhængigheder i tests

Erstat rigtige implementationer med test doubles.

Lektion 4 af 413 trin

Mocking af afhængigheder i tests er en gratis Swift Academy-lektion på CoddyKit. Dette er lektion 4 af 4. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Swift Academy, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Swift Academy-kurset indeholder 4 lektioner i alt.

Mocking af afhængigheder i test

En mock er en falsk implementering af en afhængighed, som bruges i test. Fordi vi injicerer protokoller, kan vi levere en mock i stedet for den rigtige samarbejdspartner.

En protokol til mocking

Start med en protokol, der beskriver afhængigheden. Den rigtige type og mocken overholder begge protokollen.

protocol UserStore {
    func name(for id: Int) -> String
}
struct RealStore: UserStore {
    func name(for id: Int) -> String { "User-\(id)" }
}
print(RealStore().name(for: 5))

Skriv en mock

En mock overholder protokollen, men returnerer foruddefinerede værdier, så du undgår adgang til det rigtige netværk eller den rigtige disk.

protocol UserStore { func name(for id: Int) -> String }
struct MockStore: UserStore {
    func name(for id: Int) -> String { "Mock" }
}
print(MockStore().name(for: 99))

Injicér mocken

Giv mocken til systemet under test gennem dets initialiseringsmetode. Koden under test kan ikke se forskel.

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))

Registrering af kald

En mock kan registrere, hvordan den blev brugt, så en test kan kontrollere, at afhængigheden blev kaldt korrekt.

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)

Kontrollér adfærd

Efter at have kørt koden skal du kontrollere de registrerede data. Her bekræfter vi, at den rigtige hændelse blev udløst.

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")

Fastlagte returværdier

En stub returnerer forudindstillede værdier, så du kan teste, hvordan din kode reagerer på bestemte input.

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())

Simulering af fejl

Mocks kan simulere fejltilstande, som er svære at udløse med rigtige afhængigheder, og dermed forbedre testdækningen.

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())

Deterministiske test

Fordi mocks returnerer faste værdier, er test hurtige og deterministiske uden den ustabilitet, som rigtige tjenester kan medføre.

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())

Intet testrammeværk her

I et rigtigt projekt findes disse kontroller i XCTest-assertioner. Injektionsmønsteret er identisk; kun assertionsyntaksen er anderledes.

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))

Hele forløbet

Definér en protokol, skriv typer, der overholder den, både den rigtige og en mock, injicér mocken, kør koden, og kontrollér resultatet. DI gør hvert trin muligt.

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())

Hurtigt tjek

Hvad gør mocking af en afhængighed muligt i denne tilgang?

Opsummering

En mock overholder den injicerede protokol og returnerer foruddefinerede værdier, registrerer kald eller simulerer fejl. Når du injicerer den, får du hurtige, deterministiske test. Forløbet er: Definér protokollen, skriv typer, der overholder den, både den rigtige og en mock, injicér, kør koden, og kontrollér resultatet. Det afslutter kurset i afhængighedsinjektion.

Gratis at komme i gang

Lær Swift med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
122
Lektioner
409

Ofte stillede spørgsmål

Er lektionen “Mocking af afhængigheder i tests” gratis?

Ja — alle 3 lektioner i læringssporet Swift Academy, inklusive “Mocking af afhængigheder i tests”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Swift Academy-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Mocking af afhængigheder i tests”?

Erstat rigtige implementationer med test doubles. Du øver dig i Swift Academy med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Swift Academy?

Der kræves ingen tidligere erfaring. Swift Academy på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 4 af 4.

Hvor lang tid tager lektionen “Mocking af afhængigheder i tests”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Swift Academy-lektion?

Ja. Alle Swift Academy-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Hvorfor dependency injection
  2. Constructor injection
  3. Protokolbaserede abstraktioner
  4. Mocking af afhængigheder i tests
← Tilbage til Swift Academy