Puede obtener pruebas unitarias para vistas de alertas de forma bastante fluida intercambiando la implementación 'show' de UIAlertView. Por ejemplo, esta interfaz le da una cierta cantidad de habilidades de prueba:
@interface UIAlertView (Testing)
+ (void)skipNext;
+ (BOOL)didSkip;
@end
con esta aplicación
#import <objc/runtime.h>
@implementation UIAlertView (Testing)
static BOOL skip = NO;
+ (id)alloc
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Method showMethod = class_getInstanceMethod(self, @selector(show));
Method show_Method = class_getInstanceMethod(self, @selector(show_));
method_exchangeImplementations(showMethod, show_Method);
});
return [super alloc];
}
+ (void)skipNext
{
skip = YES;
}
+ (BOOL)didSkip
{
return !skip;
}
- (void)show_
{
NSLog(@"UIAlertView :: would appear here (%@) [ title = %@; message = %@ ]", skip ? @"predicted" : @"unexpected", [self title], [self message]);
if (skip) {
skip = NO;
return;
}
}
@end
Puede escribir pruebas unitarias, por ejemplo, de esta manera:
[UIAlertView skipNext];
// do something that you expect will give an alert
STAssertTrue([UIAlertView didSkip], @"Alert view did not appear as expected");
Si desea automatizar pulsando un botón específico en la vista alerta, usted necesitará un poco más de magia. La interfaz recibe dos nuevos métodos de clase:
@interface UIAlertView (Testing)
+ (void)skipNext;
+ (BOOL)didSkip;
+ (void)tapNext:(NSString *)buttonTitle;
+ (BOOL)didTap;
@end
que van como esto
static NSString *next = nil;
+ (void)tapNext:(NSString *)buttonTitle
{
[next release];
next = [buttonTitle retain];
}
+ (BOOL)didTap
{
BOOL result = !next;
[next release];
next = nil;
return result;
}
y el método espectáculo se convierte en
- (void)show_
{
if (next) {
NSLog(@"UIAlertView :: simulating alert for tapping %@", next);
for (NSInteger i = 0; i < [self numberOfButtons]; i++)
if ([next isEqualToString:[self buttonTitleAtIndex:i]]) {
[next release];
next = nil;
[self alertView:self clickedButtonAtIndex:i];
return;
}
return;
}
NSLog(@"UIAlertView :: would appear here (%@) [ title = %@; message = %@ ]", skip ? @"predicted" : @"unexpected", [self title], [self message]);
if (skip) {
skip = NO;
return;
}
}
Esto se puede comprobar de manera similar, pero en lugar de skipNext que' d decir qué botón tocar. P.ej.
[UIAlertView tapNext:@"Download"];
// do stuff that triggers an alert view with a "Download" button among others
STAssertTrue([UIAlertView didTap], @"Download was never tappable or never tapped");
Creo que la clase posar sería más útil aquí. Tengo una sensación desagradable si el marco de prueba de mi unidad se interpone en mi código real.Podría escribir un UIAlertViewPoser que establece un indicador cuando se muestra una alerta. http://www.cocoadev.com/index.pl?ClassPosing – wjl
@wjlafrance Interesante, y sería genial si funcionara. Desafortunadamente, poseAsClass: se ha desaprobado en la Mac y nunca fue compatible con iOS. –
Sí, lo noté poco después de publicar. Bueno ... :( – wjl