Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How to Mock Protocols in Swift

Sho Ikeda
April 19, 2019

How to Mock Protocols in Swift

「Mobile Act KYOTO #1」の発表資料です #MobileAct

https://mobileact.connpass.com/event/124732/

Sho Ikeda

April 19, 2019
Tweet

More Decks by Sho Ikeda

Other Decks in Programming

Transcript

  1. How to Mock Protocols in Swift Sho Ikeda / @ikesyo

    Mobile Act KYOTO #1 2019-04-19 Fri #MobileAct
  2. Sho Ikeda / @ikesyo • ͍͚͠ΐʔʗ஑ా ᠳ • ͸ͯͳ@ژ౎ •

    εϚʔτϑΥϯΞϓϦ։ൃ • iOS / Android / React Native • Swiftίϛολʔ • https://twitter.com/ikesyo • https://github.com/ikesyo
  3. How to Mock Protocols in Swift • Manually ! •

    Sourcery: AutoMockable • SwiftyMocky • Cuckoo
  4. Sourcery: AutoMockable • https://github.com/krzysztofzablocki/Sourcery • Mocks.md • AutoMockable.stencil • ର৅ͱͳΔͷ͸

    • AutoMockable ͱ͍͏໊લͷϓϩτίϧʹ४ڌ • // sourcery: AutoMockable ͷΞϊςʔγϣϯίϝϯτͷ෇ ༩
  5. Sourcery: AutoMockable • ϝιου • ݺ͹Ε͔ͨͲ͏͔ͷνΣοΫ: ճ਺͸෼͔Βͳ͍ • Ҿ਺λϓϧͷϓϩύςΟ: ݺ͹ΕͨҾ਺ͷνΣοΫ

    • ໭Γ஋ઃఆ༻ͷϓϩύςΟ • ϓϩύςΟఆٛ • ͔ͳΓγϯϓϧ • ֎෦Ҿ਺໊͕ಉҰɾܕҧ͍ͷΦʔόʔϩʔυ͸NG • ϓϩτίϧఆٛதʹ֎෦ϑϨʔϜϫʔΫͷܕ͕ొ৔͢Δ৔߹ɺࣗ෼ͰςϯϓϨʔτΛมߋ ͯ͠importΛॻ͖Ճ͑Δඞཁ͕͋Δ
  6. Sourcery: AutoMockable • try! Swift Tokyo 2018 - Investing time

    into developer tools and experience • https://www.youtube.com/watch?v=yAQQ0cIxSF8 • SourceryΛ׆༻ͯ͠ςετΛॻ͘ϋʔυϧΛԼ͛Δ - Qiita
  7. SwiftyMocky • δΣωϦΫεͷαϙʔτ • staticϝϯόʔͷαϙʔτ • ઃఆϑΝΠϧͰimport͢ΔϑϨʔϜϫʔΫΛࢦఆՄೳ • GivenʹΑΔελϒ •

    VerifyʹΑΔϝιουݺͼग़͠ͷݕࠪ • ճ਺΍Ҿ਺ • PerformʹΑΔϝιουͷϘσΟͷࠩ͠ସ͑
  8. SwiftyMocky: Given Given(mock, .surname(for name: .value("Johnny"), willReturn: "Bravo")) Given(mock, .surname(for

    name: .any, willReturn: "Kowalsky")) print(mock.surname(for: "Johny")) // Bravo print(mock.surname(for: "Mathew")) // Kowalsky print(mock.surname(for: "Joanna")) // Kowalsky
  9. SwiftyMocky: Given Given(mock, .surname(for name: .any, willReturn: "Bravo", "Kowalsky", "Nguyen"))

    print(mock.surname(for: "Johny")) // Bravo print(mock.surname(for: "Johny")) // Kowalsky print(mock.surname(for: "Johny")) // Nguyen print(mock.surname(for: "Johny")) // and again Bravo // ...
  10. SwiftyMocky: Verify sut.usersStorage = mockStorage sut.saveUser(name: "Johny", surname: "Bravo") sut.saveUser(name:

    "Johny", surname: "Cage") sut.saveUser(name: "Jon", surname: "Snow") Verify(mockStorage, .storeUser(name: .value("Jon"), surname: .value("Snow"))) Verify(mockStorage, 3, .storeUser(name: .any, surname: .any)) Verify(mockStorage, 2, .storeUser(name: .value("Johny"), surname: .any)) Verify(mockStorage, .moreOrEqual(to: 2), .storeUser(name: .matching({ $0.count > 3 }}), surname: .any)) Verify(mockStorage, .never, .deleteUser(id: .any))
  11. Cuckoo • https://github.com/Brightify/Cuckoo • ಠࣗͷίʔυδΣωϨʔλʔ • SourceryϕʔεͰ͸ͳ͍͕ɺSourceKittenͱStencilΛ࢖͍ͬͯΔͷ͸ಉ͡ • Protocol͚ͩ͡Όͳ͘ɺClass΋αϙʔτ͍ͯ͠Δ •

    δΣωϦΫε͸ະαϙʔτ • staticϝϯόʔ΋ඇαϙʔτ • ͦͷଞͷػೳ͸SwiftyMockyͱḮ৭ͳͦ͞͏ • ߏจ͸ΑΓSwifty͔΋͠Εͳ͍
  12. Cuckoo stub(mock) { stub in when(stub.greetWithMessage("Hello world")).then { message in

    print(message) } } stub(mock) { stub in when(stub.readWriteProperty.get).thenReturn(10) when(stub.readWriteProperty.set(anyInt())).then { print($0) } }
  13. Cuckoo mock.readWriteProperty = 10 mock.readWriteProperty = 20 mock.readWriteProperty = 30

    let argumentCaptor = ArgumentCaptor<Int>() verify(mock, times(3)).readWriteProperty.set(argumentCaptor.capture()) argumentCaptor.value // Returns 30 argumentCaptor.allValues // Returns [10, 20, 30]