Заглушка OCMock для аргумента передачи по ссылке метода

У меня есть метод, который мне нужно заглушить. Метод имеет следующий вид:

BOOL myMethodWithError:(*__autoreleasing *NSError)error;

Поэтому я издевался над объектом и пытался вернуть ноль обратно через «ошибку». Я закодировал это следующим образом.

id mockMyObject = [OCMockObject mockForClass:[MyObject class]];
BOOL retVal = YES;
NSError *error = nil;
[[[mockMyObject stub] andReturn:OCMOCK_VALUE(retVal)] myMethodWithError:&error];

Когда тест запускается и фиктивный объект работает, идентификатор ссылки на ошибку изменяется. Итак, макет выдает исключение:

OCMockObject[MyObject]: вызван ожидаемый метод: myMethodWithError:0xbfffca78

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

Мне просто нужно проверить мои бизнес-правила на соответствие значению аргумента, передаваемому по ссылке, но я не могу заставить фиктивный или тестовый объект сотрудничать.

Заранее спасибо, любая помощь будет принята с благодарностью.


person Rob    schedule 01.12.2013    source источник
comment
У меня немного больше ясности в проблеме. Еще немного покопавшись в тестах исходного кода OCMock, я обнаружил, где проводились тесты, аналогичные моим. В тесте использовался [OCMArg isAnyPointer], который возвращает недействительный *. Это было нормально до ARC, но теперь ARC не допускает неявное преобразование между 'void *' и 'NSError *__autoreleasing *'. Теперь это кажется тем, что мне нужно обойти.   -  person Rob    schedule 01.12.2013
comment
Гораздо более простой способ обойти это — сделать макет вручную.   -  person Jon Reid    schedule 02.12.2013


Ответы (2)


Помимо решений, которые Бен упоминает в своем ответе (я тестировал только одно, основанное на ignoringNonObjectArgs, и оно отлично работает), я предпочитаю использовать [OCMArg anyPointer] с соответствующим приведением:

[[[myMock stub] andReturn:something] someMethod:(NSError * __autoreleasing *)[OCMArg anyPointer]];
person e1985    schedule 02.12.2013
comment
Ха! Каким-то образом я продолжал неправильно произносить anyPointer способами, которые не нравились Clang, и пропустил очевидный. знак равно - person Ben Flynn; 03.12.2013

Используйте игнорированиеNonObjectArgs

[[[[mock stub] andReturnValue:OCMOCK_VALUE((BOOL){YES})] ignoringNonObjectArgs] myMethodWithError:NULL];

Из http://ocmock.org/features/

Аргументы, которые не являются ни объектами, ни указателями или селекторами, нельзя игнорировать с помощью любого заполнителя. Однако можно указать макету игнорировать все необъектные аргументы в вызове:

[[[mock expect] ignoringNonObjectArgs] someMethodWithIntArgument:0] 

В этом случае макет примет любой вызов someMethodWithIntArgument: независимо от того, какой аргумент фактически передан. Если у метода есть объектные аргументы, а также необъектные аргументы, объектные аргументы все еще могут быть ограничены, как обычно, с помощью методов OCMArg.

Дополнительный ответ

Это также решит вашу проблему:

[[[mock stub] andReturnValue:OCMOCK_VALUE((BOOL){YES})] myMethodWithError:[OCMArg setTo:nil]];
person Ben Flynn    schedule 02.12.2013