Objective c 如何在OCMock中模拟接受句柄作为参数的方法?

Objective c 如何在OCMock中模拟接受句柄作为参数的方法?,objective-c,unit-testing,mocking,handle,ocmock,Objective C,Unit Testing,Mocking,Handle,Ocmock,我试图模拟具有以下签名的等效方法: - (NSDictionary *) uploadValues:(BOOL)doSomething error:(NSError **)error 我希望它返回一个小字典,以便我的测试能够确保代码正确使用字典。然而,无论我做什么,OCMock总是从方法返回nil,不管我如何将其剔除。在我测试的代码中,错误以nil开头,以下是我尝试过的不同方法: NSError * error = nil; [[[mock stub] andReturn:someDict]

我试图模拟具有以下签名的等效方法:

- (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是否支持以存根形式处理消息参数?如果支持,正确的方法是什么?

遗憾的是,我也没有找到一个好的解决方案。我能说的最好的方法是尽量少使用NSError**函数,然后将它放在一个独立的函数中,您可以在部分模拟中完全模拟它

我发现任何使用NSObject*(或派生)或原语值(NSInteger、BOOL等)以外的任何代码都不可能使用OCMock进行测试

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

你也可以这样做

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

但这可能会导致您的代码错误地认为您传回了一个真正的N错误。

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

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

是的,这很有道理。感谢您的见解。使用并提供接受NSError**的方法是Cocoa中首选的错误处理机制。我建议坚持这一范式,看看Andreas Järliden的答案来模拟这些方法。您的答案不正确。具体来说,以下内容似乎在expect中运行良好:错误:((NSError\uu autoreleasing**)[OCMArg anyPointer])此外,GitHub上最新版本的OCMock在OCMArg中似乎有类似的内容,
+(id\uu autoreleasing*)anyObjectRef
,您可以使用
[OCMArg anyObjectRef]
而不是
[OCMArg anyPointer]
来避免在处理指向Objective-C对象类型指针的指针(例如
NSError**
)时在ARC下出现错误。
@implementation OCMArg (Helpers)

+ (NSError *__autoreleasing *)anyError {
    return (NSError *__autoreleasing *)[OCMArg anyPointer];
}

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