Cedar Swizzle Helper Snippet

The example below shows the IBAction #closeButtonTapped. When the button is tapped, an UIView animation is triggered and the code below allows to test UIView's animateWithDuration:delay:options:animations:completion: parameters (including animation and completion blocks).

    context(@"#closeButtonTapped", ^{
        __block IMP origImpl;
        __block Method origMethod;
        __block BOOL methodHasBeenCalled;

        __block NSTimeInterval timeInterval;
        __block NSTimeInterval delayTimeInterval;
        __block UIViewAnimationOptions animationOptions;
        __block void (^animationBlock)(void);
        __block void (^completionBlock)(BOOL);
        
        beforeEach(^{
            methodHasBeenCalled = NO;
            origMethod = class_getClassMethod([UIView class], @selector(animateWithDuration:delay:options:animations:completion:));
            IMP mockBlock = imp_implementationWithBlock(^(id _self,
                                                          NSTimeInterval timeInt,
                                                          NSTimeInterval delay,
                                                          UIViewAnimationOptions options,
                                                          id animate,
                                                          id completion) {
                methodHasBeenCalled = YES;

                timeInterval = timeInt;
                delayTimeInterval = delay;
                animationOptions = options;
                animationBlock = [animate copy];
                completionBlock = [completion copy];
            });
            origImpl = method_setImplementation(origMethod, mockBlock);
            
            [viewController closeButtonTapped];
        });
        
        afterEach(^{
            method_setImplementation(origMethod, origImpl);
        });

        it(@"has triggered the animation block", ^{
            methodHasBeenCalled should be_truthy;
        });
        
        it(@"has the correct duration", ^{
            timeInterval should equal(0.2);
        });
        
        it(@"has the correct delay", ^{
            delayTimeInterval should equal(0.0);
        });
        
        it(@"has the correct animation", ^{
            animationOptions should equal(UIViewAnimationOptionCurveLinear);
        });
        
        // ...
    });