Тестирование вложенной обработки ошибок с помощью OCMock - PullRequest
3 голосов
/ 12 июля 2009

Буду очень признателен за советы по проверке ошибок с помощью OCMock.

Метод испытания

Он захватывает процесс, используя экземпляр класса AppScriptController.

@implementation ProcessGrabber

  -(void)grabProcess {
      NSError *error = nil;

      NSString *processName = [appScriptController processName:ProcessRef
                                                         error:&error];
      if(error == nil) {
         NSNumber *processID = [appScriptController processID:ProcessRef
                                                        error:&error];

          if(error == nil) {
          ... More operations...
          }
      }

      if(error) {
          [NSApp raiseError:error];
      }
  }

@end

Способ издеваться

Класс AppScriptController взаимодействует с системой, поэтому я хочу его сменить.

@implementation AppScriptController

-(NSString *)processName:(SERef *)theProcessRef error:(NSError **)theError {
    return [[theProcessRef name] error:error];
}

-(NSNumber *)processID:(SERef *)theProcessRef error:(NSError **)theError {
    return [[theProcessRef name] error:error];
}

Тест

-(void)testGrabProcess {
  NSError *error = nil;        

  OCMockObject *mock = [OCMockObject mockForClass:[AppScriptController class]];
  [[[mock expect] andReturn:@"Process Name"] processName:nil error:&error];

  // ... Somehow inject an error here...

  [[[mock expect] andReturn:34] processID:nil error:&error];

}

Проблема

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

Примеры

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

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

Независимо от того, где произошла ошибка, проверьте, что возникла правильная ошибка.

Что я пробовал

Очевидная вещь, которую нужно попробовать, - установить ошибку там, где я поставил «... Каким-то образом ввести ошибку здесь ...». Я не ожидал, что это сработает, и это не сработало.

Я искал в Google ответы и думал о том, чтобы попытаться каким-то образом обернуть ошибку в отдельном классе, но я не понимаю, как это поможет.

Я думал об этом часами, но все еще не приблизился к решению.

Может кто-нибудь помочь?

Ответы [ 4 ]

2 голосов
/ 28 января 2015

Если кто-то еще ищет это, на самом деле есть довольно простой способ сделать это с помощью OCMock:

- (void)testGrabProcess {

    OCMockObject *mock = [OCMockObject mockForClass:[AppScriptController class]];
    [[[[mock expect] andDo:^(NSInvocation *invocation) {
        NSError * __autoreleasing *anError = nil;
        [invocation getArgument:&anError atIndex:3];
        *anError = [NSError errorWithDomain:@"MYDomain" code:2323 userInfo:nil];
    }] andReturn:@"Process Name"] processName:nil error:&error];

    [[[mock expect] andReturnValue:@34] processID:nil error:(BECloudPlayerDevice *__autoreleasing *)[OCMArg anyPointer]];
}
2 голосов
/ 12 июля 2009

Мне бы очень хотелось увидеть реальный метод тестирования с реальным тестовым кодом, поскольку я чувствую, что что-то теряется при упрощении вопроса. Тем не менее, возможно, OCMock не лучший инструмент для работы, здесь? Я не уверен, что он очень хорошо обрабатывает параметры NSError ** (я никогда не пробовал). Возможно, вам лучше использовать нестандартный тестовый заглушку , а не общий фиктивный объект?

0 голосов
/ 26 марта 2013

Я решил эту проблему следующим образом:

Наличие метода в MyClass, подобного этому:

- (BOOL) myMethod:(id)someParameter error:(NSError **)error;

В тесте я делаю это:

id myMock = [OCMockObject mockForClass:[MyClass class]];
[[myMock expect] myMethod:someParameter error:(NSError *__autoreleasing *)[OCMArg anyPointer]];

И таким образом я избегаю создания пользовательского макета подкласса MyClass.

0 голосов
/ 12 июля 2009

Вы можете создать еще один тест для случая возврата nil;

-(void)testGrabProcessError {
  NSError *error = //create the error code you want to test here.;        

  OCMockObject *mock = [OCMockObject mockForClass:[AppScriptController class]];
  [[[mock expect] andReturn:nil] processName:nil error:&error];
  ...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...