I have a button press that fires off an animation, and upon completion of the animation, changes the text of a label. I'd like to write a test verifies that when the button gets pressed, eventually the text of the label changes properly.
The implementation of the button press IBAction will use [UIView animateWithDuration:animations:completion:]
. I obviously don't want my unit test to actually wait 0.5 seconds for an animation to complete.
I thought about mocking UIView, but it seems odd to inject UIView as a dependency to a view controller. Further, the mocking framework I'm using (OCMockito) doesn't seem to work well with mocking class methods.
I also thought about method swizzling or writing a testing category for UIView
, and using an implementation that does nothing but invoke the animations:
block followed by the completion:
block. That seems a bit broken to me; I worry that overriding the implementation of a class method on UIView may have unintended consequences down the road.
Being new to TDD, I'm not sure what best practice is here. Is this one of those pieces of code that should be considered "UI twiddling" and therefore it's acceptable to leave untested? Or is there some more obvious way to test this that I am missing?
Animations are another way to make visible changes to a view without requiring you to subclass and implement complex drawing code. Many properties of the UIView class are animatable, which means changes to those properties can trigger system-generated animations.
An object that manages the content for a rectangular area on the screen. Views are the fundamental building blocks of your app's user interface, and the UIView class defines the behaviors that are common to all views. A view object renders content within its bounds rectangle, and handles any interactions with that content.
A view object renders content within its bounds rectangle and handles any interactions with that content. The UIView class is a concrete class that you can instantiate and use to display a fixed background color. You can also subclass it to draw more sophisticated content.
Any UIKit based animation is internally translated into core animations. Thus, the Core Animation framework acts as a backing layer or backbone for any UIKit animation. Hence, all UIKit animation APIs are nothing but encapsulated layers of the core animation APIs in an easily consumable or convenient fashion.
I would simply make a property that determines the length of the animation and have it default to 0.5 seconds.
That way, your test can set the animation duration to 0 and observe that the label's text is updated without waiting.
This is dependency injection, and it's wildly useful if you just starting with TDD. It also has the nice side-effect of make your code more modular and less coupled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With