Unidade Cocoa testando transformações CGContext

A cobertura do teste em cacau geralmente é dividida em testes de unidade e de aplicação.

Às vezes, o teste de unidade envolverá a declaração de transformações em um CGContext. Eu sei que você pode querer agrupar chamadas CoreGraphics em métodos “simuláveis” para manter seu código testável; mas apenas no caso de você querer testar se uma transformação realmente ocorre, isso funcionou para mim em um projeto desenvolvido recentemente.

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

Depois de ter isso, você pode adicioná-lo ao rootViewController no aplicativo, em kiwi deve ser algo como:

#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

Este método funciona apenas para Transformações de Matriz de Contexto, mas nos permite testar algumas lógicas que são muito importantes para nosso aplicativo. Isso não é para teste de IU, mas para testar a lógica em métodos que, de outra forma, não seriam testados.