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

How to Mock Protocols in Swift

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for Sho Ikeda Sho Ikeda
April 19, 2019

How to Mock Protocols in Swift

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

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

Avatar for Sho Ikeda

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]