Как смоделировать класс AFHTTPClient и метод тестирования getPath: параметры: успех: отказ:?

Я новичок в AFNetworking framework. Я реализовал простой запрос GET на сервер.

@implementation MyClass
…

- (void)signInWithUsername:(NSString *)username andPassword:(NSString *)password withBlock:(SignInBlock)block {
[client getPath:@"test.json" parameters:Nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
    block(YES, [responseObject objectForKey:@"access_token"]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    block(NO, nil);
}];
}

объявление блока:

typedef void (^SignInBlock)(BOOL success, NSString *token);

Я понятия не имею, как правильно издеваться над этим объектом AFHTTPClient, чтобы проверить, был ли вызван блок из аргумента (SignInBlock) и с какими аргументами. Как я могу сделать это правильно?

Заранее спасибо.


person Tomasz Szulc    schedule 01.12.2013    source источник
comment
Ознакомьтесь с моим ответом здесь: stackoverflow .com/questions/19095322/   -  person e1985    schedule 02.12.2013


Ответы (2)


Я сделал это.

- (void)testTokenInBlockShouldBeNotNil {

id mockClient = [OCMockObject mockForClass:[AFHTTPClient class]];

[[[mockClient expect] andDo:^(NSInvocation *invocation) {

    void (^successBlock)(AFHTTPRequestOperation *operation, id responseObject) = nil;

    [invocation getArgument:&successBlock atIndex:4];

    successBlock(nil, @{@"access_token" : @"this_is_a_token"});

}] getPath:[OCMArg any] parameters:[OCMArg any] success:[OCMArg any] failure:[OCMArg any]] ;

RKObjectManager *manager = [[RKObjectManager alloc] init];
manager.HTTPClient = mockClient;

TokenBlock block = ^(NSString *token) {
    XCTAssertNotNil(token, @"");
};

CTFAPIConnection *connection = [[CTFAPIConnection alloc] initWithManager:manager];
_accounts = [[CTFAPIAccounts alloc] initWithConnection:connection];
id mockAccounts = [OCMockObject partialMockForObject:_accounts];
[mockAccounts signInWithUsername:[OCMArg any] andPassword:[OCMArg any] withBlock:block];
}
person Tomasz Szulc    schedule 02.12.2013
comment
Хорошее использование захвата блока из вызова. - person Ben Flynn; 03.12.2013

В вашем случае вам вообще не нужно издеваться, просто подтвердите, что в ваш блок отправляются правильные значения:

Рассмотрим Foo:

- (void)signInWithUsername:(NSString *)username andPassword:(NSString *)password withBlock:(SignInBlock)block
{
    if ([username isEqualToString:@"Ben"])
    {
        block(YES, @"bentoken");
    }
    else
    {
        block(NO, nil);
    }
}

Тест:

- (void)testSignInWithUsername
{
    SignInBlock testYes = (SignInBlock)^(BOOL *success, NSString *token)
    {
        STAssertTrue(success, @"Expected Ben to be true");
        STAssertEqualObjects(token, @"bentoken", @"Expected the ben token");
    };
    Foo *foo = [Foo new];
    [foo signInWithUsername:@"Ben" andPassword:@"Whatever" withBlock:testYes];
}
person Ben Flynn    schedule 02.12.2013
comment
@ e1985 e1985 Я сосредоточился на части проверки блоков, поэтому в случае с Томашем это будет связано с сетевым вызовом, а не с модульным тестом. Я не знаю, есть ли хороший модульный тест для вышеуказанного метода, поскольку client не является вашим кодом (вы можете предположить, что он вызовет соответствующий метод, который был отдельно протестирован). - person Ben Flynn; 02.12.2013
comment
Спасибо за помощь @BenFlynn. Я понял, как это сделать раньше. Прочитай мой ответ. - person Tomasz Szulc; 03.12.2013