Как мне создать макет метода, который принимает дескриптор в качестве аргумента в OCMock?
-
18-09-2019 - |
Вопрос
Я пытаюсь смоделировать метод, который имеет эквивалент следующей подписи:
- (NSDictionary *) uploadValues:(BOOL)doSomething error:(NSError **)error
Я хочу, чтобы он вернул небольшой словарь, чтобы мой тест мог убедиться, что код использует словарь правильно.однако, независимо от того, что я делаю, OCMock всегда возвращает nil из метода, независимо от того, как я его отключаю.Ошибка начинается с нуля в коде, который я тестирую, и это различные способы, которыми я пытался ее устранить:
NSError * error = nil;
[[[mock stub] andReturn:someDict] uploadValues:YES error:&error];
[[[mock stub] andReturn:someDict] uploadValues:YES error:nil];
[[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg any]];
и ни один из них не работает.Поддерживает ли OCMock дескрипторы в качестве аргументов заглушенного сообщения, и если да, то каков правильный способ это сделать?
Решение
К сожалению, я тоже не нашел хорошего решения для этого.Лучшее, что я могу сказать, это попытаться использовать NSError ** как можно меньше, а затем поместить его в изолированную функцию, которую вы можете полностью воспроизвести в своем частичном макете.
Я обнаружил, что любой код, который использует что-либо отличное от NSObject * (или производных) или примитивных значений (NSInteger, BOOL и т.д.), Практически невозможно протестировать с помощью OCMock.
Другие советы
[[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg setTo:nil]];
или
NSError* someError = ...
[[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg setTo:someError]];
Вы также могли бы сделать
[[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg anyPointer]];
но это может привести к тому, что ваш код ошибочно подумает, что вы передали обратно реальный NSError.
С ARC объявление вашего метода, вероятно, будет выглядеть следующим образом:
- (NSDictionary *) uploadValues:(BOOL)doSomething error:(NSError *__autoreleasing *)error;
Вот как я издеваюсь над этими типами методов:
BOOL mockDoSomething = YES;
NSError __autoreleasing *error = nil;
[[[mock stub] andReturn:someDict] uploadValues:OCMOCK_VALUE(mockDoSomething) error:&error];
NSError *__autoreleasing *err = (NSError *__autoreleasing *) [OCMArg anyPointer];
[[[_mockReporter stub] andReturnValue:OCMOCK_VALUE((BOOL){YES})]
yourMethodCall:err];
Я создал категорию в OCMArg, чтобы помочь в этой ситуации.
OCMArg+ Помощники.h:
@interface OCMArg (Helpers)
+ (NSError *__autoreleasing *)anyError;
@end
OCMArg+Помощники.m:
@implementation OCMArg (Helpers)
+ (NSError *__autoreleasing *)anyError {
return (NSError *__autoreleasing *)[OCMArg anyPointer];
}
@end
Затем, всякий раз, когда у меня появляется параметр ошибки, который мне нужно высмеять, используйте anyError
, вот так:
[[myMock stub] someMethodWithArg:anArg error:[OCMArg anyError]];