Objective c 创建存根时,OCMStub将OCMConstraint实例发送给real方法

Objective c 创建存根时,OCMStub将OCMConstraint实例发送给real方法,objective-c,unit-testing,ocmock,Objective C,Unit Testing,Ocmock,我正试图针对使用OCMock从REST客户机类发出(或将要发出)的请求测试URL/路径。客户端使用RestKit(使用AFNetworking)进行通信。 因此,我的计划是: 创建一个块,用于检查AFHTTPRequestOperationURL是否为所需的URL 创建AFHTTPClient的部分模拟 使用块(共1个)模拟(存根)将HttpRequestOperation:方法排入队列 创建RKObjectManager的模拟,并将其HTTPClient属性设置为 AFHTTPClient部分

我正试图针对使用OCMock从REST客户机类发出(或将要发出)的请求测试URL/路径。客户端使用RestKit(使用AFNetworking)进行通信。 因此,我的计划是:

  • 创建一个块,用于检查
    AFHTTPRequestOperation
    URL是否为所需的URL
  • 创建
    AFHTTPClient
    的部分模拟
  • 使用块(共1个)模拟(存根)将HttpRequestOperation:方法排入队列
  • 创建
    RKObjectManager
    的模拟,并将其
    HTTPClient
    属性设置为
    AFHTTPClient
    部分模拟(共2个)
  • 使用模拟管理器初始化我的客户机类的实例(从4开始)
  • 调用要检查其URL的此实例的方法
  • 验证是否调用了
    排队HttpRequestOperation:
  • 我不确定我是否弄错了OCMock,因为我找不到使用一个或多个参数的mock方法的示例。。。无论如何,这就是我努力实现目标的方式:

        void (^checkBlock)(NSInvocation *) = ^(NSInvocation *invocation) {
    
            AFHTTPRequestOperation *requestOperation = nil;
            [invocation getArgument:&requestOperation atIndex:0];
    
            XCTAssert(requestOperation != nil);
    
            NSString *path = requestOperation.request.URL.path;
            XCTAssert([path containsString:@"/rest/user/authenticate"]);
        };
    
        AFHTTPClient *httpClientMock = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:FAServerUrl]];
        OCMPartialMock(httpClientMock);
    
        [OCMStub([httpClientMock enqueueHTTPRequestOperation:[OCMArg isNotNil]]) andDo:checkBlock];
    
        RKObjectManager *objectManager = OCMClassMock([RKObjectManager class]);
    
        [OCMStub([objectManager HTTPClient]) andReturn:httpClientMock];
    
        FAUserClient *userClient = [[FAUserClient alloc] initWithUser:nil objectManager:objectManager];
    
        [userClient getAccessTokenForUsername:@"testuser"
                                     password:@"pass123"
                                      success:^(NSString *token, NSArray *roles) {
                                      }
                                      failure:^(NSInteger errorCode, NSError *error) {                                          
                                      }];
    
        OCMVerify([httpClientMock enqueueHTTPRequestOperation:OCMOCK_ANY]);
    
    但是在
    [OCMStub([httpClientMock-enqueueHTTPRequestOperation:[OCMArg isNotNil]]和do:checkBlock]上我获得了一个EXC\u BAD\u访问权限(代码=1)。
    显然,创建模拟存根(使用
    OCMStub
    )会调用待存根方法,使用给定的
    [OCMArg isNotNil]
    。我认为A:参数只是具有声明性的含义,B:这会创建一个存根,而不会立即调用该方法

    我们将非常感谢任何有助于“正确”方向的帮助或建议

    编辑:

    经过了很好的尝试:

        OCMStub([httpClientMock enqueueHTTPRequestOperation:[OCMArg checkWithBlock:^BOOL(id obj) {
            AFHTTPRequestOperation *request = (AFHTTPRequestOperation *)obj;
            NSString *path = request.request.URL.path;
            XCTAssert([path containsString:@"/rest/user/authenticate"]);
            return YES;
        }]]);
    
    …具有相同的“结果”

    最好的, 加布里埃尔编辑

    仔细看。您正在调用
    OCMPartialMock(httpClientMock)
    。这不会转换调用它的对象,而是返回部分模拟。在变量中捕获结果

    AFHTTPClient *httpClientMock = OCPartialMock([[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:FAServerUrl]]);
    
    您仍应在
    和do:
    块中进行以下更改。您还可以使用“现代”语法:

    OCMStub([myObject myMethod]).andDo(myBlock);
    
    原创

    我认为问题可能是
    和do:
    块中的代码

    [invocation getArgument:&requestOperation atIndex:0];
    
    对于所有Objective-C方法,NSInvocation在索引0和1处有两个默认参数,
    self
    \u cmd
    。尝试获取索引2处的参数


    您还可以考虑包括NSncOcto+OcMul加添加,它给出了<代码> GETAguMutTalpRexAxObjs<代码>。另一种选择是使用

    [OCMArg checkWithBlock:
    ,其中arg直接交给您的评估块。

    谢谢您的提示。不幸的是,问题依然存在
    OCMStub()
    直接调用方法(它应该是存根),将
    OCMConstraint
    作为参数传递。是的,您是对的。我没有注意到
    CCMParticialMock()
    在不更改给定实例的情况下返回mock。谢谢