2014-10-15 7 views
0

내 프로젝트는 OCMock, OHHTTPStub 및 XCTest를 사용합니다. SDK (SDK 구현)를 테스트하려고하므로 Http 응답/요청을 스텁하고 콜백 메소드에 대한 기대치를 추가하십시오. 각 유닛 테스트는 위임 메소드가 적절하게 호출되고 모든 기대 값을 설정 한 후 각 위임 메소드에 대해 거부 된 메소드 만 호출하여 지정된 메소드 만 호출되도록하는 등의 몇 가지 기대 사항을 테스트합니다. 내 단위 테스트의지연 및 거부로 확인 테스트를 실행하는 데 많은 시간이 필요합니다.

예 :

// stub http 
... here are some http stubs... 

// expect 

[[self.mockDelegate expect] didSomethigHappend:[OCMArg checkWithBlock:^BOOL(id obj) { 

    BOOL result = NO; 
    // testing parameter object 

    if(result) { 
     // call next method on SDK 
     [self.objectToTest nextMethod]; 
    } 
    return result; 

}] withError:[OCMArg isNil]]; 

// reject any other call: 
[[self.mockDelegate reject] didSomethigHappend:[OCMArg any] withError:[OCMArg any]]; 
[[self.mockDelegate reject] dodSomethig2:[OCMArg any] withError:[OCMArg any]]; 
[[self.mockDelegate reject] dodSomethig3:[OCMArg any] withError:[OCMArg any]]; 

[super.objectToTest doSomethigWithDelegate:super.mockDelegate]; // run 

[super.mockDelegate verifyWithDelay:3]; // verify 

모든 테스트를 성공적으로 통과하지만이 모든 것을 실행하는 데 시간이 많이 걸릴. 하지만 내가봤을 때, 내가 그 거부를 제거하면 모든 테스트가 3 배 빠르게 실행됩니다. 어떤 debuging 후 나는 OCMock 라이브러리 메소드의 구현을 확인하십시오

- (void)verifyWithDelay:(NSTimeInterval)delay atLocation:(OCMLocation *)location 
{ 
    NSTimeInterval step = 0.01; 
    while(delay > 0) 
    { 
     if([expectations count] == 0) 
      break; 
     [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:step]]; 
     delay -= step; 
     step *= 2; 
    } 
    [self verifyAtLocation:location]; 
} 

그리고 거부가 등록되는 경우는 모든 지연 시간을 대기하도록 "기대"변수는 항상 그 거부가 포함되어 있습니다.

아무도 같은 문제가 있습니까? 어쩌면 내가 뭔가 잘못하고 이것이 올바른 행동입니까?

답변

0

OCMock에는 버그가 있습니다. 여기

스위 즐링이 방법으로 해결이다

// stubbing verify with delay from ocmock framework 
// because ocmock if has any registered rejects 
// waits whole specified time, so we need to change this flow 
// so it will wait for all expectation has occure and after that wait some steps to make sure that any reject has not invoked 

static dispatch_once_t swizzle_token; 
dispatch_once(&swizzle_token, ^{ 
    SEL originalSelector = @selector(verifyWithDelay:); 
    SEL swizzledSelector = @selector(fake_verifyWithDelay:); 

    Method originalMethod = class_getInstanceMethod([OCMockObject class], originalSelector); 
    Method swizzledMethod = class_getInstanceMethod([VDFUsersServiceBaseTestCase class], swizzledSelector); 

    BOOL didAddMethod = 
    class_addMethod([OCMockObject class], 
        originalSelector, 
        method_getImplementation(swizzledMethod), 
        method_getTypeEncoding(swizzledMethod)); 

    if (didAddMethod) { 
     class_replaceMethod([OCMockObject class], 
          swizzledSelector, 
          method_getImplementation(originalMethod), 
          method_getTypeEncoding(originalMethod)); 
    } else { 
     method_exchangeImplementations(originalMethod, swizzledMethod); 
    } 
}); 

그리고 여기 fake_verify 방법 :

- (void)fake_verifyWithDelay:(NSTimeInterval)delay { 

NSTimeInterval step = 0.1; 
while (delay > 0) { 
    @try { 
     [self verify]; 
     break; 
    } 
    @catch (NSException *e) {} 
    [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:step]]; 
    delay -= step; 
    step += 0.1; 
} 
[self verify]; 

}

관련 문제