ich diese Einschränkung auch getroffen. Die Grundidee besteht darin, respondsToSelector
zu überschreiben: (was NICHT zuverlässig von OCMock verspottet werden kann).
Ich machte die folgende Klasse, die das für Sie tut. Sie können es dann wie folgt verwenden:
GCOCMockOptionalMethodSupportingObject
erweitern und implementieren Ihr Protokoll
@interface GCTestDelegate : GCOCMockOptionalMethodSupportingObject <GCDelegate>
@end
@implementation GCTestDelegate
//required methods
- (void)requiredMethod{
}
@end
// create your testdelegate
self.classBeingTested.delegate = [OCMock partialMockForObject:[GCTestDelegate new]];
[self.classBeingTested.delegate markSelectorAsImplemented:@selector(optionalMethod:)];
[[self.classBeingTested.delegate expect] optionalMethod:self.classBeingTested];
[self.classBeingTested doSomethingThatwillCheckIfYourDelegateRespondsToYourOptionalMethod];
Wenn Sie nicht markSelectorAsImplemented
nennen, dann classBeingTested
erhalten NO für respondsToSleectorForThatMethod
Ich habe habe der Code dafür hier. Ich benutze das sehr gut. Danke an jer auf #iphonedev für mich auf diesem Weg (overriding respondsToSelector
war seine Idee, ich habe einige verrückte Laufzeit Methode Zugabe - das ist viel sauberer methinks).
hier ist der Code
/**
* This class is specifically useful and intended for testing code paths that branch
* pending implementation of optional methods.
* OCMock does not support mocking of protocols with unimplemented optional methods.
* Further compounding the issue is the fact that OCMock does not allow mocking of
* respondsToSelector (in fact, it does but the behaviour is undefined),
* As such this class can be extending to implement a given protocol, the methods can be mocked/expected
* as normal, but in addition we can tell the class to report it conforms to a protocol method or not.
*
*/
@interface GCOCMockOptionalMethodSupportingObject : NSObject
- (void)markSelectorAsImplemented:(SEL)aSelector;
- (void)unmarkSelectorAsImplemented:(SEL)aSelector;
@end
#import "GCOCMockOptionalMethodSupportingObject.h"
@interface GCOCMockOptionalMethodSupportingObject()
@property(nonatomic, strong) NSMutableArray *implementedSelectors;
@end
@implementation GCOCMockOptionalMethodSupportingObject {
}
//////////////////////////////////////////////////////////////
#pragma mark init
//////////////////////////////////////////////////////////////
- (id)init {
self = [super init];
if (self) {
self.implementedSelectors = [NSMutableArray array];
}
return self;
}
//////////////////////////////////////////////////////////////
#pragma mark public api
//////////////////////////////////////////////////////////////
- (void)markSelectorAsImplemented:(SEL)aSelector {
if (![self isImplemented:aSelector]) {
[self.implementedSelectors addObject:NSStringFromSelector(aSelector)];
}
}
- (void)unmarkSelectorAsImplemented:(SEL)aSelector {
for (NSString *selectorValue in [self.implementedSelectors mutableCopy]) {
SEL storedSelector = NSSelectorFromString(selectorValue);
if (sel_isEqual(aSelector, storedSelector)) {
[self.implementedSelectors removeObject:selectorValue];
break;
}
}
}
//////////////////////////////////////////////////////////////
#pragma mark private impl
//////////////////////////////////////////////////////////////
- (BOOL)isImplemented:(SEL)aSelector {
for (NSString *selectorValue in self.implementedSelectors) {
SEL storedSelector = NSSelectorFromString(selectorValue);
if (sel_isEqual(aSelector, storedSelector)) {
return YES;
}
}
return NO;
}
//////////////////////////////////////////////////////////////
#pragma mark overridden
//////////////////////////////////////////////////////////////
- (BOOL)respondsToSelector:(SEL)aSelector {
if ([self isImplemented:aSelector]) {
return YES;
} else {
return [super respondsToSelector:aSelector];
}
}
@end
Lassen Sie mich eine Gegenfrage stellen. Warum sollte der Mock NEIN zurückgeben, wenn er gefragt wird, ob er auf die optionale Methode reagiert? Diese Methode ist immerhin Teil des Protokolls. Wäre es möglich, eine Klasse zu verspotten, die das Protokoll implementiert? Wenn diese Klasse die optionale Methode nicht implementiert, würde der Mock tun, was Sie erwarten. –
Der Grund ist, dass ich gerne testen möchte, ob sich eine Klasse korrekt verhält, wenn sie einen Delegaten hat, der keine optionale Delegate-Methode implementiert. – extremeboredom