Есть ли способ заставить [super init] потерпеть неудачу в логических тестах? - PullRequest
2 голосов
/ 25 августа 2011

Я хотел бы написать логический тест для проверки на случай сбоя [super init].

У меня есть такой метод init:

- (id)init
{
    if ((self = [super init]) != nil)
    {
        // init my members
    }
    return self;
}

Кто-нибудь знает, как я могу заставить [super init] вернуть nil для проверки этого случая? «super» - это NSObject в этом случае, и в настоящее время я использую SenTestKit для логических тестов.

Ответы [ 4 ]

2 голосов
/ 25 августа 2011

Вы можете добавить промежуточный родительский класс, который не прошел метод init:

@interface InitFailTest : NSObject
{
}

- (id)init;
@end

@implementation InitFailTest
- (id)init
{
    if (gFailSuperInitTest)
        return nil;
    else
        return [super init];
}
@end

@interface MyClass : InitFailTest  // instead of NSObject
...

Но это кажется немного тяжеловесным. Если ваш родительский класс - NSObject, то, честно говоря, я бы не стал слишком беспокоиться о тестировании, если его метод init не удался. Если ваш родительский класс является чем-то другим, и у него есть задокументированные условия отказа, тогда, конечно, вы должны проверить их.

1 голос
/ 25 августа 2011

Вы можете добавить оператор #define, например #define INIT_FAIL_TESTING. Затем в родительском классе, который вы хотите протестировать (при условии, что у вас есть к нему доступ), поместите следующее в начало его метода init:

#if INIT_FAIL_TESTING
return nil
#endif

или, в качестве альтернативы, в классе, который вы действительно хотите проверить, выполните следующее:

- (id)init
{
#if INIT_FAIL_TESTING
    self = nil;
#else
    self = [super init];
#endif

    if (self == nil) {
    //...
    }
    return self;
}

Второй вариант, вероятно, лучше, так как он не требует, чтобы у вас был доступ к родительскому классу, и вы должны быть в состоянии предположить, что все, что родитель будет делать в своем методе init, вообще не произошло. Вы просто проверяете, получили ли вы действующий родительский экземпляр, чего вы явно не получили, установив self в nil.

1 голос
/ 25 августа 2011

Вы могли бы, но это было бы очень сложно.Вам нужно пошлить init на NSObject (гугл "метод swizzle").Там действительно нет причин для этого.Единственный способ, которым NSObject init может потерпеть неудачу, - это если у вас полностью не хватает памяти, и это настолько малопонятный случай в настольных и мобильных приложениях, что его тестирование не стоит затрат на его создание.Вы даже не сможете написать обработчик ошибок ObjC для него, потому что у вас полностью недостаточно памяти, и ObjC едва может функционировать без выделения небольшого объема памяти.

Если вы действительно хотите протестировать этот случай,Вам лучше использовать тестовый класс, который возвращает nil из init и проверить, работает ли остальная часть системы.Но это и должно быть очень туманным делом, которого я бы не стал преследовать.

0 голосов
/ 25 августа 2011

Если все, что вы делаете, это тестируете случай, когда [super init] равен nil, не могли бы вы просто заменить его на nil и посмотреть, что произойдет?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...