Я работал с Objective C и Cocoa / iOS и тестировал, как издеватель.( Определение )
Что мне следует использовать?
Мне не нравится ни один из этих.Но я должен использовать один ... если нет других вариантов, о которых я не знаю.
1.Внедрение зависимостей
Это загромождает мой код, особенно когда SUT имеет 2/3 соавторов.Если SUT необходимо передать 1/2 параметра, все начинает выглядеть очень грязно.
Я понимаю, что за пределами 3 слишком много зависимостей, и объект должен быть разделен на другие части ...но даже с 2 зависимостями и 1 параметром все равно безобразно, как грех.
2.Установка внутреннего состояния
Это портит внутреннее устройство класса, которое, как я думал, было большим нет-нет в тестировании.
Средства доступа определенно отсутствуют - они предоставляют данные, о которых никто не должен знать.Я могу использовать setValue: forKey: ... но это похоже на ужасный взлом.
Это также означает, что я должен инициировать SUT, затем заменить реальных коллабораторов на фиктивных, а затем запустить тестируемый метод,что кажется грязным.
Мой вопрос
Какой самый лучший способ издеваться над сотрудниками в Цели C при выполнении BDD?
Код
Насмешка с использованием 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