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

    View full-size slide

  2. Sho Ikeda / @ikesyo
    • ͍͚͠ΐʔʗ஑ా ᠳ
    • ͸ͯͳ@ژ౎
    • εϚʔτϑΥϯΞϓϦ։ൃ
    • iOS / Android / React Native
    • Swiftίϛολʔ
    • https://twitter.com/ikesyo
    • https://github.com/ikesyo

    View full-size slide

  3. How to Mock Protocols in Swift
    • Manually
    !
    • Sourcery: AutoMockable
    • SwiftyMocky
    • Cuckoo

    View full-size slide

  4. Sourcery: AutoMockable
    • https://github.com/krzysztofzablocki/Sourcery
    • Mocks.md
    • AutoMockable.stencil
    • ର৅ͱͳΔͷ͸
    • AutoMockable ͱ͍͏໊લͷϓϩτίϧʹ४ڌ
    • // sourcery: AutoMockable ͷΞϊςʔγϣϯίϝϯτͷ෇

    View full-size slide

  5. Sourcery: AutoMockable
    • ϝιου
    • ݺ͹Ε͔ͨͲ͏͔ͷνΣοΫ: ճ਺͸෼͔Βͳ͍
    • Ҿ਺λϓϧͷϓϩύςΟ: ݺ͹ΕͨҾ਺ͷνΣοΫ
    • ໭Γ஋ઃఆ༻ͷϓϩύςΟ
    • ϓϩύςΟఆٛ
    • ͔ͳΓγϯϓϧ
    • ֎෦Ҿ਺໊͕ಉҰɾܕҧ͍ͷΦʔόʔϩʔυ͸NG
    • ϓϩτίϧఆٛதʹ֎෦ϑϨʔϜϫʔΫͷܕ͕ొ৔͢Δ৔߹ɺࣗ෼ͰςϯϓϨʔτΛมߋ
    ͯ͠importΛॻ͖Ճ͑Δඞཁ͕͋Δ

    View full-size slide

  6. Sourcery: AutoMockable
    • try! Swift Tokyo 2018 - Investing time into developer tools
    and experience
    • https://www.youtube.com/watch?v=yAQQ0cIxSF8
    • SourceryΛ׆༻ͯ͠ςετΛॻ͘ϋʔυϧΛԼ͛Δ - Qiita

    View full-size slide

  7. SwiftyMocky
    • https://github.com/MakeAWishFoundation/SwiftyMocky
    • Sourceryϕʔε
    • AutoMockableͷϚʔΫΛͦͷ··࢖༻
    • ΑΓߴػೳͳςϯϓϨʔτͱϥϯλΠϜ
    • SourceryͷAutoMockableςϯϓϨʔτ͔ΒҠߦ͠΍͍͢

    View full-size slide

  8. SwiftyMocky
    • δΣωϦΫεͷαϙʔτ
    • staticϝϯόʔͷαϙʔτ
    • ઃఆϑΝΠϧͰimport͢ΔϑϨʔϜϫʔΫΛࢦఆՄೳ
    • GivenʹΑΔελϒ
    • VerifyʹΑΔϝιουݺͼग़͠ͷݕࠪ
    • ճ਺΍Ҿ਺
    • PerformʹΑΔϝιουͷϘσΟͷࠩ͠ସ͑

    View full-size slide

  9. 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

    View full-size slide

  10. 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
    // ...

    View full-size slide

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

    View full-size slide

  12. SwiftyMocky: Perform
    Perform(
    mock,
    .methodThatTakesCompletionBlock(
    completion: .any,
    perform: { completion in
    completion(true,nil)
    }
    )
    )

    View full-size slide

  13. Cuckoo
    • https://github.com/Brightify/Cuckoo
    • ಠࣗͷίʔυδΣωϨʔλʔ
    • SourceryϕʔεͰ͸ͳ͍͕ɺSourceKittenͱStencilΛ࢖͍ͬͯΔͷ͸ಉ͡
    • Protocol͚ͩ͡Όͳ͘ɺClass΋αϙʔτ͍ͯ͠Δ
    • δΣωϦΫε͸ະαϙʔτ
    • staticϝϯόʔ΋ඇαϙʔτ
    • ͦͷଞͷػೳ͸SwiftyMockyͱḮ৭ͳͦ͞͏
    • ߏจ͸ΑΓSwifty͔΋͠Εͳ͍

    View full-size slide

  14. 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)
    }
    }

    View full-size slide

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

    View full-size slide

  16. !
    Happy Swift Mocking/Testing

    View full-size slide

  17. WE ARE HIRING
    https://hatenacorp.jp/recruit/

    View full-size slide

  18. Thank you
    Sho Ikeda / @ikesyo

    View full-size slide