How to mock UIApplication in Swift?
You are close. Use a protocol for the functions you need.
protocol UIApplicationProtocol {
func openURL(url: NSURL) -> Bool
}
extension UIApplication: UIApplicationProtocol {}
Then you just need to use the protocol instead of the class
extension Inviter {
convenience init(usingMockApplication mockApplication: UIApplicationProtocol) {
self.init()
application = mockApplication
}
}
You will need to modify the Inviter
class to use UIApplicationProtocol
as well.
Mock UIApplication open function in iOS 10
The solution was to give the function (in the BSApplicationProtocol
) a different name.
open()
--> open2()
for example. (NOTE: You should probably come up with a better function name than this though)
Obviously then you have to change the function name in the extension
and the function named called from within my openAppSettings
function.
I'm not exactly sure why I didn't have to name openURL
something different. The only difference I see between these two is that OpenURL
returns a Bool
and the new iOS 10 version has default values.
iOS how to test a method that calls the [[UIApplication sharedApplication] openUrl:someUrl]
I deleted the new class with the static method and to solve my problem I used a partial mock from the Specta framework:id mockApplication = [OCMockObject partialMockForObject:[UIApplication sharedApplication]];
I guess this is a better solution. (I didn't know partial mocks before)
How Can I Unit Test Calling of iOS Application Delegate Methods?
Because you want to test a callback… just have tests invoke the callback directly, as if the GitHub framework invoked it.
Write simple tests around the happy path. Then, because you're dealing with external data you can't control, write tests that (if Swift allows) invoke the callback with strange options
.
XCTestCase: UIApplication.shared.keyWindow returns nil
Create a window and assign the view controller.
let testBoard = UIStoryboard(name: "TestStoryboard", bundle: Bundle(for: type(of: self)))
let vc = testBoard.instantiateViewController(withIdentifier: "TestController")
let window = UIWindow()
window.rootViewController = vc
window.makeKeyAndVisible()
vc.view.layoutIfNeeded()
// Add test here
I notice after that you're also calling vc.view
and viewDidLoad
. I'd recommend just accessing the view to get it to load and not calling viewDidLoad
implicitely - personally I use vc.view.layoutIfNeeded()
Depending on what you actually need to test, for me it's very rare to have to assign the view controller to the window itself. You can normally get away with just creating an instance of the view controller, and if you're testing any of the UI code also ensuring the view is populated.
One of the only times I've needed to assign the view controller to a window is when testing things like navigation, where I want to assert that another view controller is being presented modally due to some action.
Related Topics
Difference Between Packed VS Normal Data Type
How to Set Inputview for Textfield in Swiftui
How to Handle Touch Gestures in Swiftui in Swift Uikit Map Component
Cannot Form Weak Reference to Instance of Class Nstextview
How to Draw a Scnnode Always in Front of Others
Swiftui - How to Use Oncommand with Nsmenuitem on MACos
Swiftui: Dismiss View Within MACos Navigationview
How to Filter Events Created for the Current Date in the Realm Swift
Why Do Servicesubscribercellularproviders Return Nil? (In iOS 12)
How to Automatically Reflect Coredata+Icloud Changes in Swiftui View
How to Call Initializer for Subclass of Generic Type
Difference Between Dispatchqueue Types in Swift
Convincing Swift That a Function Will Never Return, Due to a Thrown Exception
Swift How to Cast from Int? to String
Guarantees About the Lifetime of a Reference in a Local Variable
Facebookshare Causing Compiler Error After Update
Swift - Converting from Unsafepointer<Uint8> with Length to String