Correction On Testing UIAlertController
Two month ago I published a post about How To Test UIAlertController. A reader found out that the test doesn’t work as I expected:
@dasdom Your tests work, but ur convienience init in MockUIAction is never triggered - u can’t override convienience inits. Seems an ios bug
— Larhythimx (@Larhythmix) 25. November 2015
Larhythimx is totally right. The init method of the mock is never
called. The reason why I didn’t see this when I wrote the test is, that
the handler is actually called. It looks like the real UIAlertAction
does
use handler as the hidden internal variable to store the handler closure
of the action. This is fragil and Larhythimx mentions in another tweet
that the handler is nil in test he tries to write.
So as the golden way (i.e. write tests without changing the implementation) does not work here, let’s go for silver.
First we add a class method to UIAlertAction
that
creates actions. Add the following extension in ViewController.swift
:
In the MockAlertAction
add
this override:
In the implementation code we can now use the class methods to create the alert actions:
To make sure we do really test, what we think we do test, rename the
handler
property in MockAlertAction
to
mockHandler:
In addition we add tests for the mock title of the actions. The test for the cancel action then looks like this:
This test would have failed in the previous version because as the init method got never called the mock title did not get set.
You can find the corrected version on github.
Thanks again Larhythimx for the tweet!