我想为单例类MySingleton
编写测试
MySingletone.h:
@interface MySingleton : NSObject
@property (class, readonly, strong) Class_B* shared;
@end
MySingleton.m:
@interface MySingleton()
{
SomeClass* _someClass;
}
@end
@implementation MySingletone
+ (MySingleton*)shared {
static MySingleton* mySingleton;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
SomeClass* someClass = [[SomeClass alloc] init];
mySingleton = [[MySingleton alloc] initWithSomeClass:someClass];
});
return mySingleton;
}
- (instancetype)initWithSomeClass:(SomeClass*)someClass {
self = [super init];
if (self) {
_someClass = someClass;
}
return self;
}
@end
在测试中,我希望能够用假的替换具体的SomeClass
,所以我定义了一个SomeClass
应符合的协议:
@protocol SomeProtocol
@end
@interface SomeClass : NSObject <SomeProtocol>
@end
@interface MySingleton : NSObject
{
id<SomeProtocol> _someClass;
}
@property (class, readonly, strong)MySingleton* shared;
- (instancetype)initWithSomeClass:(id<SomeProtocol>)someClass;
@end
@implementation MySingleton
+ (MySingleton*)shared {
static MySingleton* mySingleton;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
SomeClass* someClass = [[SomeClass alloc] init];
mySingleton = [[MySingleton alloc] initWithSomeClass:someClass];
});
return mySingleton;
}
- (instancetype)initWithSomeClass:(id<SomeProtocol>)someClass {
self = [super init];
if (self) {
_someClass = someClass;
}
return self;
}
@end
现在在我的测试中我定义了一个假类:
@interface someClassFake : NSObject <SomeProtocol>
@end
用它初始化MySingleton
:
SomeClassFake* someFakeClass = [[SomeClassFake alloc] init];
MySingletone* mySingleton = [[MySingleton alloc] initWithObject: someClassFake];
我留下的唯一问题是,在测试套装中,虽然我没有使用具体的SomeClass
,但我仍然依赖它,因为它被用在shared
getter中,链接器将要求我为它提供实现。什么是最好的设计解决方案,以便我的测试服不依赖于SomeClass
?
我想出的最佳解决方案是将shared
getter移动到一个类别:
MySingletone + Shared.h:
@interface MySingleton (Shared)
@property (class, readonly, strong)MySingleton* shared;
@end
MySMySingletone + Shared.m:
@implementation MySingleton (Shared)
+ (MySingleton*)shared {
static MySingleton* mySingleton;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
SomeClass* someClass = [[SomeClass alloc] init];
mySingleton = [[MySingleton alloc] initWithSomeClass:someClass];
});
return mySingleton;
}
@end
而现在,在实际代码中导入MySingletone + Shared.h而不是MySingletone.h