Cocoa Unit testing CGContext transformations
Test coverage in cocoa usually is divided on Unit and Application testing.
Sometimes unit testing will involve asserting transformations on a CGContext. I know you might want to wrap CoreGraphics calls into "mockable" methods to keep your code testable; but just in case you want to test if a transformation actually occurs this is something that worked for me in a recent developed project.
TestView.h
#import <UIKit/UIKit.h>
#import <QuartzCore/QuartzCore.h>
@interface ABTestView : UIView
@property (nonatomic) CGContextRef drawingContext;
@end
TestView.m
#import "ABTestView.h"
@implementation ABTestView
- (void)drawRect:(CGRect)rect
{
self.drawingContext = UIGraphicsGetCurrentContext();
}
@end
Once you have this you can add it to the rootViewController on the app, in kiwi should be something like:
#import "MyView.h"
#import "ABTestView.h"
#import "ABAppDelegate.h"
SPEC_BEGIN(MyViewSpec)
__block UIView *testView;
__block UIView *myView;
__block CGContextRef graphicsContext;
__block CGAffineTransform transformMatrix;
beforeEach(^{
// first we get the app delegate
app *appDelegate = [[UIApplication sharedApplication] delegate];
// we init our testView
CGRect aFrame = CGRectMake(0,0,100,100);
testView = [TestView.alloc initWithFrame:aFrame];
//add it to the rootViewController
[app.window.rootViewController.view addSubview:testView];
// this is a little weird. If we don't add this the context
// won't be available. I bet there is better ways to wait for it.
[[theValue(testView.drawingContext) shouldEventually] beNonNil];
// Now we have a context to test
graphicsContext = testView.drawingContext;
// Init our view with some transformations
// or call the methods that transforms the ContextMatrix
myView = [MyView.alloc initWithFrame:aFrame flipped:YES];
[testView addSubview:myView];
// We now capture the Transformation Matrix
transformMatrix = CGContextGetCTM(graphicsContext);
});
afterEach(^{
// don't forget to clean after you.
CGContextRelease(graphicsContext);
testView = nil;
myView = nil;
transformMatrix = nil;
});
it(@"should transform the context matrix", ^{
// And now we can assert warever transformations we applied
// to the Affine Transformation Matrix.
[[theValue(transformMatrix.a) should] equal:theValue(-1)];
});
SPEC_END
This method works only for Context Matrix Transformations, but it allow us to test some logic that is very important for our app. This is not for UI testing, but for testing logic on methods that otherwise will go untested.
Written by Javier Guerra
Related protips
1 Response
Way to contribute!