2011-12-11 4 views
1

Я хотел бы написать тесты блочных ящиков для метода, который вызывает другой с задержкой. Это своего рода выглядит следующим образом:Единичное тестирование метода с задержкой в ​​Objective-C

- (void) doSomething { 
    // Do something 
    [self performSelector:@selector(doSomethingLater) withObject:nil afterDelay:kDelay]; 
} 

- (void) doSomethingLater { } 

Где kDelay постоянная и doSomethingLater является частным. Проблема в том, что kDelay составляет 1 секунду, и я не хочу замедлять выполнение модульных тестов.

Что было бы лучшим способом модульного теста doSomething под черным ящиком (или насколько это возможно)?

Единственное, что приходит на ум - добавить метод к классу, чтобы изменить значение kDelay, но это может быть использовано другим разработчиком случайно. Существует ли менее инвазивная альтернатива?

ответ

0

Я не знаю, было ли это менее инвазивным, но вы можете использовать метод -[NSObject performSelector:withObject:afterDelay:] со своей собственной версией, которая не задерживается.

Swizzling означает замену реализации метода во время выполнения. Ознакомьтесь с бесплатным JRSwizzle library.

+0

Думаю, я бы сказал, что это инвазивное по-другому. –

+0

Проблема с этим подходом заключается в том, что если по какой-то причине кто-то решает изменить performSelector для другого метода с задержкой, тогда тест будет медленным, и никто не узнает, почему. – hpique

+0

Было бы здорово, если бы у вас зависали постоянные. – hpique

0

Первое, на что я буду смотреть, это обнаружение того, что метод был выполнен. Так как @Rob сказал, я бы посмотрел на swizzling по-другому. Вероятно, один локальный тест, который установил bool, чтобы указать, что он был вызван.

Следующая проблема заключается в сокращении задержки. Поскольку KDelay является константой, вы не можете ничего с этим поделать. Вы можете изменить его на частную собственность или что-то, что вы можете получить в тесте и установить, но по-прежнему конфиденциально для производственного кода.

Другой вариант (который я не рассматривал, чтобы убедиться, что это возможно!) Заключается в том, чтобы не беспокоиться об обнаружении выполняемого метода, но посмотрите, можете ли вы обнаружить, что вызов представляет собой стек циклов запуска, ожидая исполнения. Если вы обнаружите наличие ожидающего вызова, а не самого вызова, вы можете сделать это немедленно, и задержка становится неактуальной.

0

Будет ли ваш тест быть уверенным, что doSomethingLater был вызван и что он сделал то, что он предполагал, и все, что вы пытаетесь сделать, это сократить временную задержку? Если это так, я рекомендую вам создать частный метод, который возвращает постоянное значение doSomething. Что-то вроде:

@implementation MyClass 

- (NSUInteger) getDelay { 
    return kDelay; 
} 

@end 

Затем вы можете гасите реализацию getDelay во время выполнения, используя различные функции вещей как OCMock рамок другого теста.

 Смежные вопросы

  • Нет связанных вопросов^_^