我如何在OCMock中模拟一个接受句柄作为参数的方法?

时间:2009-08-17 16:13:36

标签: objective-c unit-testing mocking handle ocmock

我正在尝试模拟一个具有以下签名等效的方法:

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

我希望它返回一个小字典,以便我的测试可以确保代码正确使用字典。但是,无论我做什么,OCMock总是从方法中返回nil,无论我如何将其存根。错误在我正在测试的代码中以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是否支持处理作为存根消息参数,如果是,那么正确的方法是什么?

5 个答案:

答案 0 :(得分:48)

[[[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。

答案 1 :(得分:3)

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

答案 2 :(得分:3)

NSError *__autoreleasing *err = (NSError *__autoreleasing *) [OCMArg anyPointer];

[[[_mockReporter stub] andReturnValue:OCMOCK_VALUE((BOOL){YES})]
   yourMethodCall:err];

答案 3 :(得分:3)

我在OCMArg上创建了一个类别以帮助解决这种情况。

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

然后,每当我有一个错误参数,我需要模拟,使用anyError,如下:

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

答案 4 :(得分:-3)

可悲的是,我也没有找到一个好的解决方案。我能说的最好的是尝试尽可能小地使用NSError **,然后将它放在一个孤立的函数中,你可以完全模拟你的部分模拟。

我发现任何使用除NSObject *(或派生)或原始值(NSInteger,BOOL等)以外的任何代码的代码几乎不可能使用OCMock进行测试。