如何在ARC的OCMock中模拟**参数

Posted

技术标签:

【中文标题】如何在ARC的OCMock中模拟**参数【英文标题】:How to mock ** parameter in OCMock in ARC 【发布时间】:2013-08-17 05:31:15 【问题描述】:

我的方法的一个参数是 **error 并且我的项目处于 ARC 模式。当为此方法编写存根以调用模拟方法时,我将参数设置为低于可能的值。要么导致编译错误,要么无法匹配调用模拟方法的参数。

    OCMOCK_ANY [OCMArg anyPointer] 创建了一个 NSError 对象错误并说 [OCMArg setTo:error]。

没有任何作用。

如何模拟这种方法?请指教。

编辑

-(id)init

    self = [super init];

    if (self) 
        id wcm = [OCMockObject partialMockForObject:self];
        [[[wcm stub] andCall:@selector(mockGetWakeupCallsForRoomNumber:error:)    onObject:self] getWakeupCallsForRoomNumber:OCMOCK_ANY error:((NSError __autoreleasing **)    [OCMArg anyPointer])];
        //[[[wcm stub] andCall:@selector(testMockMethod) onObject:self] testMethod];

    
    return self;



-(void)testMethod

    NSLog(@"Original");


-(void)testMockMethod

    NSLog(@"Mock");

-(NSArray*)mockGetWakeupCallsForRoomNumber:(NSString*)roomNumber error:(NSError**)error

    @throw @"Mock method called";


-(NSArray*)getWakeupCallsForRoomNumber:(NSString*)roomNumber error:(NSError**)error


模拟 testMockMethod 有效。

【问题讨论】:

【参考方案1】:

你可以使用setTo:anyPointer如果你施放它:

[[[mockFoo expect] andReturn:nil] someMethodWithError:((NSError __autoreleasing **)[OCMArg anyPointer])];

或:

NSError *error;
[[[mockFoo expect] andReturn:nil] someMethodWithError:((NSError __autoreleasing **)[OCMArg setTo:error])];

这是一个使用您发布的方法通过的测试用例:

@interface Foo : NSObject

-(NSArray*)mockGetWakeupCallsForRoomNumber:(NSString*)roomNumber error:(NSError**)error;
-(NSArray*)getWakeupCallsForRoomNumber:(NSString*)roomNumber error:(NSError**)error;

@end

@implementation Foo

-(NSArray*)mockGetWakeupCallsForRoomNumber:(NSString*)roomNumber error:(NSError**)error

    return @[@"bar"];


-(NSArray*)getWakeupCallsForRoomNumber:(NSString*)roomNumber error:(NSError**)error

    return nil;


@end

@interface SomeTest : SenTestCase 
@end

@implementation SomeTest

-(void)testMethod

    Foo *foo = [Foo new];
    id wcm = [OCMockObject partialMockForObject:foo];
    [[[wcm stub] andCall:@selector(mockGetWakeupCallsForRoomNumber:error:) onObject:foo] getWakeupCallsForRoomNumber:OCMOCK_ANY error:((id __autoreleasing *)[OCMArg anyPointer])];
    NSError *error;
    NSArray *calls = [wcm getWakeupCallsForRoomNumber:@"foo" error:&error];
    STAssertEquals(calls[0], @"bar", @"should match");


@end

【讨论】:

[[[wcm stub] andCall:@selector(mockGetWakeupCallsForRoomNumber:error:) onObject:self] getWakeupCallsForRoomNumber:OCMOCK_ANY 错误:((NSError __autoreleasing **)[OCMArg anyPointer])];调用不调用模拟方法。请帮忙。 请将测试用例和您正在测试的代码添加到您的问题中。 添加了代码。这是在负责连接后端服务器的库中。我的意图是能够提供模拟,直到后端实现所需的服务。 这是我们可以在 OCMock 中改进的地方吗?有什么方法可以声明 anyPointer/setTo: 方法以便不需要强制转换? @Galaxy 看到我更新的答案,通过测试用例。在您添加的代码中,您似乎正在尝试创建一个测试类的部分模拟,我不希望它表现良好。但是在模拟另一个类的真实案例中,它工作得很好。【参考方案2】:

最后这就是我实现的。

[
 [[wcm stub] 
           andCall:@selector(getWakeupCallsForRoomNumber:error:serverMessage:) 
   onObject:self]
   getWakeupCallsForRoomNumber:OCMOCK_ANY
                         error:((NSError *__autoreleasing *)[OCMArg anyPointer]) 
                 serverMessage:((NSString *__autoreleasing *)[OCMArg anyPointer])];

【讨论】:

以上是关于如何在ARC的OCMock中模拟**参数的主要内容,如果未能解决你的问题,请参考以下文章

将 OCMock 与 Facebook 一起使用

如何使用 OCMock 验证静态方法

在现代风格的 OCMock 中使用 ignoringNonObjectArgs 时崩溃

OCMock 对带有参数的方法进行 OCMock 并返回一个值

在 NSMutableAttributedString 上模拟“initWithAttributedString”的 OCMock 失败

使用 OCMock 发生意外崩溃,在 NSString 上模拟“mutableCopy”