Вспомогательные функции в спецификациях Киви

У меня есть несколько повторяющихся спецификаций, которые я бы хотел сделать DRY. Общая функциональность не поддается переходу в блок beforeEach. По существу, это создание объекта и 4 строки для каждого из 12 объектов, я хотел бы превратить эти 4 строки в один вызов функции.

Где я могу помещать вспомогательные функции в спецификацию Kiwi?

В RSpec я могу просто поместить def между spec-блоками, но это не представляется возможным здесь. Я даже пробовал пропустить макрос SPEC_END и добавить этот контент сам, чтобы я мог добавлять функции внутри @implementation из SPEC_BEGIN, но это тоже не работает.

Коррекция... Я могу управлять чем-то подобными работами с ручным кодированием макроса SPEC_END. У меня был конец} неправильно установлен. Но все же, он терпит неудачу, потому что метод не находится в @interface.

Ответы

Ответ 1

Создайте свою вспомогательную функцию как блок сразу после SPEC_BEGIN:

SPEC_BEGIN(MySpec) 

NSDate* (^dateFromString) (NSString *) = ^NSDate* (NSString *dateString) {
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    [dateFormatter setTimeStyle:NSDateFormatterNoStyle];
    [dateFormatter setDateFormat:@"MM-dd-yyyy"];
    return [dateFormatter dateFromString:dateString];
};


describe(@"something", ^{
    NSDate *checkDate = dateFromString(@"12-01-2005");

...
});

SPEC_END

Ответ 2

Вы также можете создать прямую функцию C над областью SPEC_BEGIN().

NSString *makeAString () {
    return @"A String";
}

Или, если у вас есть вспомогательные функции, которые будут использоваться в нескольких файлах Spec, поместите эти функции в отдельный файл и импортируйте заголовок. Я нашел, что это отличный способ очистить мои спецификации.

Ответ 3

супермарин предлагает следующий метод:

@implementation KWSpec(Additions)

+ (void)myHelperMethod:(Car*)car {
            [[car shouldNot] beNil];
        };

@end

SPEC_BEGIN(FooBarSpec)

describe(@"A newly manufactured car", ^{
    it(@"should not be nil", ^{
        [self myHelperMethod:[CarFactory makeNewCar]];
    });
});

SPEC_END

Другой вариант: Даг предлагает:

SPEC_BEGIN(FooBarSpec)

void (^myHelperMethod)(Car*) = ^(Car* car){
        [[car shouldNot] beNil];
    };

describe(@"A newly manufactured car", ^{
    it(@"should not be nil", ^{
        myHelperMethod([CarFactory makeNewCar]);
    });
});

SPEC_END

Хорошая вещь в том, что он хорошо поддается асинхронным сценариям:

SPEC_BEGIN(FooBarSpec)

__block BOOL updated = NO;

void (^myHelperAsync)() = ^()
{
    [[expectFutureValue(theValue(updated)) shouldEventually] beYes];
};

describe(@"The updater", ^{
    it(@"should eventually update", ^{
         [[NSNotificationCenter defaultCenter] addObserverForName:"updated" 
                                                 object:nil 
                                                 queue:nil 
                                            usingBlock:^(NSNotification *notification)
         {
             updated = YES;
         }];
         [Updater startUpdating];
         myHelperAsync();
    });
});

SPEC_END

Наконец, если ваш вспомогательный метод находится в другом классе, gantaa предлагает умный взлом:

@interface MyHelperClass

+(void)externalHelperMethod:(id)testCase forCar:(Car*)car
{
    void (^externalHelperMethodBlock)() = ^(){
        id self = testCase; //needed for Kiwi expectations to work
        [[car shouldNot] beNil];
    };
    externalHelperMethodBlock();
}

@end

SPEC_BEGIN(FooBarSpec)

describe(@"A newly manufactured car", ^{
    it(@"should not be nil", ^{
        [MyHelperClass externalHelperMethod:self forCar:[CarFactory makeNewCar]];
    });
});

SPEC_END