2012-06-25 29 views
4

如何驗證傳遞塊是否正確執行?OCMock測試傳遞塊是否正確執行

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{ 
    [self updatePostalCode:newLocation withHandler:^(NSArray *placemarks, NSError *error) { 
    // code that want to test 
     CLPlacemark *placemark = [placemarks objectAtIndex:0]; 
     self.postalCode = [placemark postalCode]; 
     _geocodePending = NO; 
    }]; 

    .... 
} 

我想知道,郵編,_geocodePending設置正確,但我無法弄清楚如何與OCMock做到這一點。

添加的代碼

id mockSelf = [OCMockObject partialMockForObject:_location]; 

    id mockPlacemart = (id)[OCMockObject mockForClass:[CLPlacemark class]]; 

    [[[mockPlacemart stub] andReturn:@"10170"] postalCode]; 

    [mockSelf setGeocodePending:YES]; 
    [mockSelf setPostalCode:@"00000"]; 

    [self.location handleLocationUpdate]([NSArray arrayWithObject:mockPlacemart], nil); 

    STAssertFalse([mockSelf geocodePending], @"geocodePending should be FALSE"); 
    STAssertTrue([[mockSelf postalCode] isEqualToString:@"10170"], @"10170", @"postal is expected to be 10170 but was %@" , [mockSelf postalCode]); 

回答

6

從你的類中的方法返回您的處理程序塊。 There are a few good reasons to do this,包括可測試性。

- (void (^)(NSArray *, NSError *))handleLocationUpdate { 
    __weak Foo *weakself = self; 
    return ^(NSArray *placemarks, NSError *error) { 
     CLPlacemark *placemark = [placemarks objectAtIndex:0]; 
     weakself.postalCode = [placemark postalCode]; 
     weakself.geocodePending = NO; 
    } 
} 

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation 
{ 
    [self updatePostalCode:newLocation withHandler:[self handleLocationUpdate]]; 

    .... 
} 

然後,在您的測試:

-(void)testLocationUpdates { 
    id mockPlacemark = [OCMockObject mockForClass:[CLPlacemark class]]; 
    [[[mockPlacemark stub] andReturn:@"99999"] postalCode]; 

    myClass.geocodePending = YES; 
    myClass.postalCode = @"00000"; 

    [myClass handleLocationUpdate]([NSArray arrayWithObject:mockPlacemark], nil); 

    expect(myClass.geocodePending).toBeFalsy; 
    expect(myClass.postalCode).toEqual(@"99999"); 
} 
+0

感謝那些完美地工作和文章解釋了智慧的屁股,但我不明白'[MyClass的handleLocationUpdate]([NSArray的arrayWithObject:mockPlacemark]零); '並且永遠不會看到'expect()。... ...'我可以參考這些嗎? 而我把我的代碼複製你的問題,我理解對嗎? – sarunw

+0

如果按照列出的方式定義方法,那麼'[myClass handleLocationUpdate]'返回該塊。您將該塊作爲函數執行,並傳遞包含您的模擬的地標數組。 –

+0

'expect()'來自Pete Kim的優秀匹配框架[Expecta](https://github.com/petejkim/expecta)。我們在我們所有的項目中都使用它。 –