【发布时间】:2018-12-27 08:57:07
【问题描述】:
我想为单例类编写测试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?
【问题讨论】:
标签: objective-c unit-testing testing dependency-injection dependencies