tôi nhấn hạn chế này là tốt. Ý tưởng cơ bản là ghi đè respondsToSelector
: (KHÔNG THỂ được OCMock giả mạo một cách đáng tin cậy).
Tôi đã thực hiện lớp học sau đây thực hiện việc này cho bạn. Sau đó bạn có thể sử dụng nó như sau:
mở rộng GCOCMockOptionalMethodSupportingObject
, và thực hiện các giao thức của bạn
@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];
Nếu bạn không gọi markSelectorAsImplemented
, sau đó classBeingTested
bạn sẽ nhận được NO cho respondsToSleectorForThatMethod
Tôi đã đặt mã cho nó ở đây. Tôi đang sử dụng điều này để có hiệu quả tuyệt vời. Nhờ jer trên #iphonedev để đặt tôi ra trên con đường này (ghi đè respondsToSelector
là ý tưởng của mình, tôi đã làm một số bổ sung phương pháp thời gian chạy điên - đây là methinks sạch hơn nhiều).
đây là các mã
/**
* 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
Hãy để tôi đặt một câu hỏi ngược lại. Tại sao giả lập trả về NO khi được hỏi liệu nó có phản hồi phương thức tùy chọn hay không. Phương thức đó là một phần của giao thức. Có thể giả lập một lớp thực hiện giao thức không? Nếu lớp đó không thực hiện phương thức tùy chọn thì giả lập sẽ làm những gì bạn mong đợi. –
Lý do là tôi muốn thử nghiệm rằng một lớp hoạt động chính xác khi nó có một đại biểu không thực hiện một phương thức ủy nhiệm tùy chọn. – extremeboredom