Created
March 25, 2024 13:20
-
-
Save GRGBISHOW/dcdead820b0c922d10278d0de3c35c1b to your computer and use it in GitHub Desktop.
Testability with protocol witness. Have you ever reached to point where protocol based mock gets complex, and doesn't provide variance and flexibility, well here is a small idea how protocol witness will solve the problem
This file contains 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
//MARK:- ------------------------------------- Main Target --------------------------------------------------------- | |
struct DeviceInfo { | |
var isTablet: Bool { UIDevice.current.userInterfaceIdiom == .pad } | |
var vendorIdentifler: () -> String? = { UIDevice.current.identifierForVendor?.uuidString } | |
var isPhone: Bool { UIDevice.current.userInterfaceIdiom == .phone } | |
var systemName: () -> String = { UIDevice.current.systemName } | |
var systemversion: () -> String = { UIDevice.current.systemVersion } | |
var batteryLevel: () -> Float = { | |
UIDevice.current.isBatteryMonitoringEnabled = true | |
return UIDevice.current.batteryLevel | |
} | |
var batteryState: () -> UIDevice.BatteryState = { | |
UIDevice.current.isBatteryMonitoringEnabled = true | |
return UIDevice.current.batteryState | |
} | |
} | |
struct DependentSystem { | |
lazy var device = DeviceInfo() | |
// add other dependent systems | |
} | |
var DependencyStore = DependentSystem() // Single instance in whole app | |
// Your some viewModel | |
class SomeViewModel { | |
var shouldSendNotification = false | |
func someFunction() { | |
//Some Business logic | |
shouldSendNotification = DependencyStore.device.batteryState() == .full | |
} | |
} | |
//MARK:- ------------------------------------- Test Target --------------------------------------------------------- | |
// DeviceInfo mock | |
extension DeviceInfo { | |
static let mock: Self = Self(vendorIdentifler: { "1235" }, | |
systemName: { "iPadOS"}, | |
systemversion: { "17.2" }, | |
batteryLevel: { 0.5 }, | |
batteryState: { .charging } | |
) | |
} | |
// DependentSystem mock | |
extension DependentSystem { | |
static let mock: Self = .init(device: .mock) | |
} | |
// SomeViewModel Test | |
final class SomeViewModelTests: XCTestCase { | |
var viewModel: SomeViewModel! | |
override func setUp() { | |
super.setUp() | |
DependencyStore = .mock | |
viewModel = SomeViewModel() | |
} | |
override func tearDown() { | |
viewModel = nil | |
super.tearDown() | |
} | |
func test_someFunction() { | |
viewModel.someFunction() | |
XCTAssertFalse(viewModel.shouldSendNotification) | |
DependencyStore.device.batteryState = { .full } | |
viewModel.someFunction() | |
XCTAssertTrue(viewModel.shouldSendNotification) | |
DependencyStore.device.batteryState = { .charging } | |
viewModel.someFunction() | |
XCTAssertTrue(viewModel.shouldSendNotification) | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment