Skip to content

Commit

Permalink
Add ability and tests for mocking dynamic properties
Browse files Browse the repository at this point in the history
  • Loading branch information
Nick Gillett committed Aug 17, 2015
1 parent 01b8a03 commit e28b05e
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 1 deletion.
32 changes: 31 additions & 1 deletion Source/OCMock/OCClassMockObject.m
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,37 @@ - (void)initializeForClassObject

- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
return [mockedClass instanceMethodSignatureForSelector:aSelector];
NSMethodSignature *signature = [mockedClass instanceMethodSignatureForSelector:aSelector];
if (signature == nil) {
objc_property_t property = class_getProperty(mockedClass, [NSStringFromSelector(aSelector) cStringUsingEncoding:NSASCIIStringEncoding]);
if (property) {
const char *attrsStr = property_getAttributes(property);
if (attrsStr) {
NSArray *components = [[NSString stringWithCString:attrsStr
encoding:NSASCIIStringEncoding] componentsSeparatedByString:@","];
BOOL isDynamic = NO;
NSString *typeStr = nil;
for (NSString *component in components) {
if ([component isEqualToString:@"D"]) {
//property is @dynamic, but we can synthesize the signature
isDynamic = YES;
} else if ([component hasPrefix:@"T"]) {
typeStr = [component substringFromIndex:1];
}
}

if (isDynamic) {
NSRange r = [typeStr rangeOfString:@"\""];
if (r.location != NSNotFound) {
typeStr = [typeStr substringToIndex:r.location];
}
const char *str = [[NSString stringWithFormat:@"%@@:", typeStr] cStringUsingEncoding:NSASCIIStringEncoding];
signature = [NSMethodSignature signatureWithObjCTypes:str];
}
}
}
}
return signature;
}

- (Class)mockObjectClass
Expand Down
48 changes: 48 additions & 0 deletions Source/OCMockTests/OCMockObjectTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,22 @@ - (void)receiveNotification:(NSNotification *)aNotification

@end


@interface TestClassWithDynamicProperties : NSObject
@property(nonatomic, readonly) NSDictionary *anObject;
@property(nonatomic, readonly) NSUInteger aUInt;
@property(nonatomic, readonly) NSInteger aInt;

@end

@implementation TestClassWithDynamicProperties
@dynamic anObject;
@dynamic aUInt;
@dynamic aInt;

@end


static NSString *TestNotification = @"TestNotification";


Expand Down Expand Up @@ -935,6 +951,38 @@ - (void)testArgumentConstraintsAreOnlyCalledAsOftenAsTheMethodIsCalled
}


- (void)testCanMockDynamicProperty {
mock = [OCMockObject mockForClass:[TestClassWithDynamicProperties class]];
NSDictionary *testDict = @{ @"test-key": @"test-value" };
[[[mock expect] andReturn:testDict] anObject];

NSUInteger someUInt = 5;
[[[mock expect] andReturnValue:OCMOCK_VALUE(someUInt)] aUInt];

NSInteger someInt = -10;
[[[mock expect] andReturnValue:OCMOCK_VALUE(someInt)] aInt];

NSDictionary *result = [mock anObject];
XCTAssertEqualObjects(testDict, result);

XCTAssertEqual(-10, [mock aInt]);
XCTAssertEqual(5, [mock aUInt]);

[mock verify];
}


- (void)testNSURLSessionMock {
mock = [OCMockObject mockForClass:[NSURLSessionTask class]];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.google.com"]];

[[[mock expect] andReturn:request] originalRequest];

XCTAssertEqualObjects(request, [mock originalRequest]);
[mock verify];
}


@end


0 comments on commit e28b05e

Please sign in to comment.