我一直在使用Objective C和Cocoa/iOS並像測試者一樣進行測試。 (Definition)在ObjectiveC中做BDD時嘲笑合作者的最好方法是什麼?
- 我想嘲笑使用OCMock的對象的協作者。
有目標C做這兩種方式我所知道的:
- 依賴注入
- 設置內部狀態 - 無論是通過訪問器或setValue方法:forKey:
我應該使用哪一種?
我不喜歡這些。但我必須使用一個...除非我還沒有其他選項。
1.依賴注入
這雜波我的代碼,尤其是當SUT有2/3的合作者。如果SUT需要通過1/2參數,事情看起來確實非常混亂。
我明白,遠遠超過3,有太多的依賴關係,對象應該分成其他部分...但即使有2個依賴關係和1個參數,它仍然是醜陋的罪過。
2.設置內部狀態
這打亂了類的內部 - 我覺得這是一個很大的禁忌測試。
訪問者絕對不在 - 他們暴露的數據是沒有人應該知道的。 我可以使用setValue:forKey:...但這感覺像一個可怕的黑客。
這也意味着我必須初始化SUT,然後換出真正的模擬合作伙伴,然後運行測試中的方法,這感覺很混亂。
我的問題
什麼是做BDD時,模擬出的目標C合作者的最好方法是什麼?
代碼
懲戒使用的setValue:forKey:
@interface JGCompositeCommand : JGCommand <JGCompositeCommandProtocol> {
NSMutableArray *commands;
JGCommandFinderFactory *commandFinderFactory;
}
-(id <JGCommandProtocol>)initWithName:(NSString *)name_ recoverer:(id <JGCommandRecoveryProtocol>)recoverer_ executor:(id <JGCommandExecutorProtocol>)executor_;
@end
@implementation JGCompositeCommand
-(id)initWithName:(NSString *)name_ recoverer:(id)recoverer_ {
self = [super initWithName:name_ recoverer:recoverer_];
if (self) {
commands = [NSMutableArray array];
commandFinderFactory = [[JGCommandFinderFactory alloc] init];
}
return self;
}
-(id <JGCommandProtocol>)commandWithName:(NSString *)name_ {
return [[commandFinderFactory commandFinderWithCommandName:name_ andCommands:commands] findCommandWithName];
}
@end
@interface JGCommandTestCase : SenTestCase {
JGCompositeCommand *compositeCommand;
OCMockObject *commandFinderFactoryMock;
}
@end
@implementation JGCommandTestCase
-(void)setUp {
[super setUp];
compositeCommand = [[JGCompositeCommand alloc] initWithName:@"" recoverer:nil];
commandFinderFactoryMock = [OCMockObject mockForClass:[JGCommandFinderFactory class]];
// Hack alert! Ugh.
[compositeCommand setValue:commandFinderFactoryMock forKey:@"commandFinderFactory"];
}
-(void)testGivenCommandNotFoundShouldThrow {
// ** Setup **
[[[commandFinderFactoryMock expect] andReturn:...] commandFinderWithCommandName:... andCommands:...];
// ** Execute **
[compositeCommand commandWithName:@"Blah"];
// ** Asserts **
[commandFinderFactoryMock verify];
}
@end
我很困惑 - 當然,這意味着每一位合作者都是單身?這肯定意味着大多數班級都變成了單身人士。我認爲一個單身人士是一個反模式。 – 2012-02-19 10:17:08
我想這取決於你的意思是「每一位合作者」。當然還有其他的獲取和配置對象的模式。您選擇的取決於您的需求。例如,筆尖是依賴注入的一種形式,所以在筆尖中配置的任何東西都可以在測試時注入。至於單身人士作爲反模式,我認爲主要的批評是他們很難作爲協作者測試,這種方法試圖解決這個問題。看看http://blog.securemacprogramming.com/2011/02/on-singletons/。 – 2012-02-20 18:05:33