Last active
May 9, 2022 14:46
-
-
Save fxm90/106fd802f869d3d259d672d0416b66fa to your computer and use it in GitHub Desktop.
Example on how to elegantly test a delegate protocol.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ScreenOverlayViewModel.swift | |
// | |
// Created by Felix Mau on 12.10.19. | |
// Copyright © 2019 Felix Mau. All rights reserved. | |
// | |
protocol ScreenOverlayViewModelDelegate: AnyObject { | |
func screenOverlayViewModelDidUpdate(alpha: CGFloat) | |
} | |
final class ScreenOverlayViewModel { | |
// MARK: - Public properties | |
weak var delegate: ScreenOverlayViewModelDelegate? | |
// MARK: - Public methods | |
func showOverlay() { | |
delegate?.screenOverlayViewModelDidUpdate(alpha: 1.0) | |
} | |
func hideOverlay() { | |
delegate?.screenOverlayViewModelDidUpdate(alpha: 0.0) | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ScreenOverlayViewModelTestCase.swift | |
// | |
// Created by Felix Mau on 12.10.19. | |
// Copyright © 2019 Felix Mau. All rights reserved. | |
// | |
import XCTest | |
final class ScreenOverlayViewModelTestCase: XCTestCase { | |
// MARK: - Private properties | |
private var delegateMock: ScreenOverlayViewModelDelegateMock! | |
private var viewModel: ScreenOverlayViewModel! | |
// MARK: - Public methods | |
override func setUp() { | |
super.setUp() | |
delegateMock = ScreenOverlayViewModelDelegateMock() | |
viewModel = ScreenOverlayViewModel() | |
viewModel.delegate = delegateMock | |
} | |
override func tearDown() { | |
viewModel = nil | |
delegateMock = nil | |
super.tearDown() | |
} | |
// MARK: - Test method `showOverlay` | |
func testShowOverlayShouldInformDelegateToUpdateAlphaToOne() { | |
// When | |
viewModel.showOverlay() | |
// Then | |
XCTAssertEqual(delegateMock.invokedMethod, .screenOverlayViewModelDidUpdate(alpha: 1.0)) | |
} | |
// MARK: - Test method `hideOverlay` | |
func testHideOverlayShouldInformDelegateToUpdateAlphaToZero() { | |
// When | |
viewModel.hideOverlay() | |
// Then | |
XCTAssertEqual(delegateMock.invokedMethod, .screenOverlayViewModelDidUpdate(alpha: 0.0)) | |
} | |
} | |
// MARK: - Mocks | |
private final class ScreenOverlayViewModelDelegateMock: ScreenOverlayViewModelDelegate { | |
// MARK: - Types | |
enum DelegateMethod: Equatable { | |
case screenOverlayViewModelDidUpdate(alpha: CGFloat) | |
} | |
// MARK: - Public properties | |
private(set) var invokedMethod: DelegateMethod? | |
// MARK: - `ScreenOverlayViewModelDelegate` Protocol | |
func screenOverlayViewModelDidUpdate(alpha: CGFloat) { | |
invokedMethod = .screenOverlayViewModelDidUpdate(alpha: alpha) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In case you need to verify multiple delegate methods are called, you can change the type of the property
invokedMethod
to an array:and in the delegate protocol method use
append()
, to add all invoked methods to that array: