unit test objective objective-c unit-testing mocking handle ocmock

objective-c - objective - unit testing swift 4



¿Cómo me burlo de un método que acepta un identificador como un argumento en OCMock? (5)

Estoy tratando de burlarme de un método que tiene el equivalente de la siguiente firma:

- (NSDictionary *) uploadValues:(BOOL)doSomething error:(NSError **)error

Quiero que devuelva un pequeño diccionario para que mi prueba pueda asegurarse de que el código usa el diccionario correctamente. sin embargo, no importa lo que haga, OCMock siempre devuelve nil desde el método, independientemente de cómo lo apague. El error comienza como nulo en el código que estoy probando, y estas son las diferentes maneras en que he intentado aplastarlo:

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]];

y ninguno de ellos funciona. ¿Soporta OCMock los manejadores como argumentos de mensajes aplastados y, de ser así, cuál es la forma correcta de hacerlo?


Con ARC, su declaración de método probablemente se verá así:

- (NSDictionary *) uploadValues:(BOOL)doSomething error:(NSError *__autoreleasing *)error;

Aquí es cómo me burlo de estos tipos de métodos:

BOOL mockDoSomething = YES; NSError __autoreleasing *error = nil; [[[mock stub] andReturn:someDict] uploadValues:OCMOCK_VALUE(mockDoSomething) error:&error];


Creé una categoría en OCMArg para ayudar con esta situación.

OCMArg + Helpers.h:

@interface OCMArg (Helpers) + (NSError *__autoreleasing *)anyError; @end

OCMArg + Helpers.m:

@implementation OCMArg (Helpers) + (NSError *__autoreleasing *)anyError { return (NSError *__autoreleasing *)[OCMArg anyPointer]; } @end

Luego, cada vez que tenga un error de parámetro que necesito anyError , use anyError , así:

[[myMock stub] someMethodWithArg:anArg error:[OCMArg anyError]];


Lamentablemente, tampoco he encontrado una buena solución para esto. Lo mejor que puedo decir es tratar de hacer que el uso del NSError ** sea lo más pequeño posible, y luego colocarlo en una función aislada que pueda simular completamente en su simulacro parcial.

Estoy descubriendo que cualquier código que use algo que no sea un NSObject * (o derivado) o valores primitivos (NSInteger, BOOL, etc.) es prácticamente imposible de probar con OCMock.


[[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg setTo:nil]];

o

NSError* someError = ... [[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg setTo:someError]];

Tambien podrias hacer

[[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg anyPointer]];

pero esto podría hacer que su código piense incorrectamente que usted devolvió un NSError real.


NSError *__autoreleasing *err = (NSError *__autoreleasing *) [OCMArg anyPointer]; [[[_mockReporter stub] andReturnValue:OCMOCK_VALUE((BOOL){YES})] yourMethodCall:err];