Skip to content

Instantly share code, notes, and snippets.

@mistersourcerer
Created March 15, 2011 19:25
Show Gist options
  • Save mistersourcerer/871273 to your computer and use it in GitHub Desktop.
Save mistersourcerer/871273 to your computer and use it in GitHub Desktop.
A light-light-light-weight Double/Mock framework for Objective-C
#import <Foundation/Foundation.h>
#import "NSObject+TestExtension.h"
@interface Doubler : NSObject {
}
+(id)named:(NSString *)name;
-(BOOL)shouldHaveReceived:(NSString *)message with:(id)parameter;
-(BOOL)shouldHaveReceived:(NSString *)message;
@end
#import "Doubler.h"
@implementation Doubler
+(id)named:(NSString *)name {
return [[[Doubler alloc] init] autorelease];
}
#pragma mark -
-(BOOL)shouldHaveReceived:(NSString *)message with:(id)parameter {
NSArray *parameters = parameter;
if (![parameter respondsToSelector:@selector(count)]) {
parameters = [NSArray arrayWithObject:parameter];
}
return [[called objectForKey:message] isEqual:parameters];
}
-(BOOL)shouldHaveReceived:(NSString *)message {
return [called objectForKey:message] != nil;
}
@end
#import "GTMSenTestCase.h"
#import "Doubler.h"
#import "NSObject+TestExtension.h"
@interface DoublerTests : GTMTestCase { }
@end
@implementation DoublerTests
//Doubler should...
-(void) test_validate_an_expectation
{
id doubler = [Doubler named:@"xpto"];
NSString *method = @"entaroAdum:";
NSString *parameter = @"parameter";
[doubler entaroAdum:parameter];
BOOL isExpectationValid = [doubler shouldHaveReceived:method with:parameter];
STAssertTrue(isExpectationValid, @"Doubler instance should validate a method call with a parameter.");
}
@end
#import <Foundation/Foundation.h>
@interface NSObject (TestExtension)
NSMutableDictionary *stubs;
NSMutableDictionary *called;
-(void)stub:(NSString *)method andReturn:(id)result;
@end
#import "NSObject+TestExtension.h"
@implementation NSObject(TestExtension)
#pragma mark -
-(NSMutableDictionary *)stubs {
if(stubs == nil) {
stubs = [[NSMutableDictionary dictionary] retain];
}
return stubs;
}
-(NSMutableDictionary *)called {
if(called == nil) {
called = [[NSMutableDictionary dictionary] retain];
}
return called;
}
-(void)fazNada {
NSLog(@"::: esse método não faz nada");
}
-(void)stub:(NSString *)method andReturn:(id)result {
// checar se o método existe para substituir implementação
SEL originalMethodSelector = NSSelectorFromString(method);
BOOL methodExists = [self respondsToSelector:originalMethodSelector];
if (methodExists) {
//method_exchangeImplementations(originalMethodSelector, @selector(fazNada));
}
[[self stubs] setObject:result forKey:method];
}
-(id)returnTheValue:(NSString *)method {
return [[self stubs] objectForKey:method];
}
#pragma mark -
#pragma mark missing methods
- (NSArray *)getParametersToInvocation:(NSInvocation *)invocation {
NSArray *args = [NSStringFromSelector([invocation selector]) componentsSeparatedByString: @":"];
NSMutableArray *parameters = [NSMutableArray array];
for (int i=2; i<[args count]+1; i++) {
NSString *arg;
[invocation getArgument:&arg atIndex:i];
// Workaround // not allowed to put nil in an array
if (arg == nil) {
arg = @"";
}
// pensar em uma forma melhor de armazenar isso...
[parameters addObject:arg];
}
return [NSArray arrayWithArray:parameters];
}
-(void)invoke:(NSInvocation *)invocation andReturnValue:(id)value {
[invocation setTarget:self];
[invocation setSelector:@selector(returnTheValue:)];
[invocation setArgument:value atIndex:3];
[invocation invoke];
}
- (void)forwardInvocation:(NSInvocation *)invocation {
NSString *selectorString = NSStringFromSelector([invocation selector]);
[[self called] setObject:[self getParametersToInvocation:invocation] forKey:selectorString];
BOOL isStubConfigured = [[self stubs] objectForKey:selectorString] != nil;
if (isStubConfigured) {
[self invoke:invocation andReturnValue:[[self stubs] objectForKey:selectorString]];
}
}
- (NSMethodSignature *)methodSignatureForSelector:(SEL)selector
{
return [NSMethodSignature signatureWithObjCTypes:"@^v@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"];;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment