2013-09-30 8 views
9

मैं नीचे इस कोड के रूप में AFNetworking साथ JSON डेटा पुनः प्राप्त करने के लिए एक GET अनुरोध कर रहा हूँ करने के लिए:कैसे इकाई परीक्षण AFNetworking अनुरोध

 NSURL *url = [NSURL URLWithString:K_THINKERBELL_SERVER_URL]; 
    AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url]; 
    Account *ac = [[Account alloc]init]; 
    NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET" path:[NSString stringWithFormat:@"/user/%@/event/%@",ac.uid,eventID] parameters:nil]; 

    AFHTTPRequestOperation *operation = [httpClient HTTPRequestOperationWithRequest:request 
                      success:^(AFHTTPRequestOperation *operation, id responseObject) { 
                       NSError *error = nil; 
                       NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error]; 
                       if (error) { 
                       } 

                       [self.delegate NextMeetingFound:[[Meeting alloc]init] meetingData:JSON]; 

                      } 
                      failure:^(AFHTTPRequestOperation *operation, NSError *error){ 
                      }]; 
    [httpClient enqueueHTTPRequestOperation:operation]; 

बात मैं इस डेटा के आधार एक इकाई परीक्षण बनाने के लिए चाहते हैं, लेकिन है मैं यह नहीं चाहते कि परीक्षा वास्तव में अनुरोध करेगी। मैं चाहता हूं कि एक पूर्वनिर्धारित संरचना प्रतिक्रिया के रूप में वापस आ जाएगी। मैं यूनिट परीक्षण के लिए नया हूं, और थोड़ा OCMock दबाया लेकिन यह समझने के लिए कि इसका प्रबंधन कैसे किया जाए।

+0

आप शायद [नोकिला] (https://github.com/luisobo/Nocilla) पर एक नज़र रखना चाहते हैं। यह आपको मौजूदा 'NSURLConnections' में आसानी से हुक करने और उनके व्यवहार को परिभाषित करने की अनुमति देता है। – mAu

उत्तर

12

कई प्रश्न आपके प्रश्न के बारे में टिप्पणी करने के लिए। सबसे पहले, आपका कोड परीक्षण करना मुश्किल है क्योंकि यह सीधे AFHTTPClient बना रहा है। मुझे नहीं पता कि यह क्यों है क्योंकि यह सिर्फ एक नमूना है, लेकिन आपको इसे इंजेक्ट करना चाहिए (नीचे नमूना देखें)।

दूसरा, आप अनुरोध बना रहे हैं, फिर AFHTTPRequestOperation और फिर आप इसे संलग्न करते हैं। यह ठीक है लेकिन आप AFHTTP क्लाइंट विधि getPath का उपयोग कर प्राप्त कर सकते हैं: पैरामीटर: सफलता: विफलता:।

मुझे उस सुझाए गए HTTP स्टबिंग टूल (नोसीला) के साथ अनुभव नहीं है लेकिन मुझे लगता है कि यह NSURLProtocol पर आधारित है। मुझे पता है कि कुछ लोग इस दृष्टिकोण का उपयोग करते हैं, लेकिन मैं अपनी खुद की रबड़ प्रतिक्रिया वस्तुओं को बनाना पसंद करता हूं और http क्लाइंट को नकल करता हूं जैसे कि आप निम्न कोड में देखते हैं।

रेट्रिवर वह वर्ग है जिसे हम परीक्षण करना चाहते हैं जहां हम AFHTTPClient इंजेक्ट करते हैं। ध्यान दें कि मैं सीधे उपयोगकर्ता और ईवेंट आईडी पास कर रहा हूं, क्योंकि मैं चीजों को सरल और परीक्षण करने में आसान रखना चाहता हूं। तो फिर अन्य जगह में आप इस विधि के लिए खाते को यूआईडी मूल्य से होकर गुजरेगा और इतने पर ... हेडर फाइल इस के समान दिखेगा:

#import <Foundation/Foundation.h> 

@class AFHTTPClient; 
@protocol RetrieverDelegate; 

@interface Retriever : NSObject 

- (id)initWithHTTPClient:(AFHTTPClient *)httpClient; 

@property (readonly, strong, nonatomic) AFHTTPClient *httpClient; 

@property (weak, nonatomic) id<RetrieverDelegate> delegate; 

- (void) retrieveEventWithUserId:(NSString *)userId eventId:(NSString *)eventId; 

@end 


@protocol RetrieverDelegate <NSObject> 

- (void) retriever:(Retriever *)retriever didFindEvenData:(NSDictionary *)eventData; 

@end 

कार्यान्वयन फ़ाइल:

#import "Retriever.h" 
#import <AFNetworking/AFNetworking.h> 

@implementation Retriever 

- (id)initWithHTTPClient:(AFHTTPClient *)httpClient 
{ 
    NSParameterAssert(httpClient != nil); 

    self = [super init]; 
    if (self) 
    { 
     _httpClient = httpClient; 
    } 
    return self; 
} 

- (void)retrieveEventWithUserId:(NSString *)userId eventId:(NSString *)eventId 
{ 
    NSString *path = [NSString stringWithFormat:@"/user/%@/event/%@", userId, eventId]; 

    [_httpClient getPath:path 
       parameters:nil 
       success:^(AFHTTPRequestOperation *operation, id responseObject) 
    { 
     NSDictionary *eventData = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:NULL]; 
     if (eventData != nil) 
     { 
      [self.delegate retriever:self didFindEventData:eventData]; 
     } 
    } 
       failure:nil]; 
} 

@end 

और परीक्षण :

#import <XCTest/XCTest.h> 
#import "Retriever.h" 

// Collaborators 
#import <AFNetworking/AFNetworking.h> 

// Test support 
#import <OCMock/OCMock.h> 

@interface RetrieverTests : XCTestCase 

@end 

@implementation RetrieverTests 

- (void)setUp 
{ 
    [super setUp]; 
    // Put setup code here; it will be run once, before the first test case. 
} 

- (void)tearDown 
{ 
    // Put teardown code here; it will be run once, after the last test case. 
    [super tearDown]; 
} 

- (void) test__retrieveEventWithUserIdEventId__when_the_request_and_the_JSON_parsing_succeed__it_calls_didFindEventData 
{ 
    // Creating the mocks and the retriever can be placed in the setUp method. 
    id mockHTTPClient = [OCMockObject mockForClass:[AFHTTPClient class]]; 

    Retriever *retriever = [[Retriever alloc] initWithHTTPClient:mockHTTPClient]; 

    id mockDelegate = [OCMockObject mockForProtocol:@protocol(RetrieverDelegate)]; 
    retriever.delegate = mockDelegate; 

    [[mockHTTPClient expect] getPath:@"/user/testUserId/event/testEventId" 
          parameters:nil 
          success:[OCMArg checkWithBlock:^BOOL(void (^successBlock)(AFHTTPRequestOperation *, id)) 
    { 
     // Here we capture the success block and execute it with a stubbed response. 
     NSString *jsonString = @"{\"some valid JSON\": \"some value\"}"; 
     NSData *responseObject = [jsonString dataUsingEncoding:NSUTF8StringEncoding]; 

     [[mockDelegate expect] retriever:retriever didFindEventData:@{@"some valid JSON": @"some value"}]; 

     successBlock(nil, responseObject); 

     [mockDelegate verify]; 

     return YES; 
    }] 
          failure:OCMOCK_ANY]; 

    // Method to test 
    [retriever retrieveEventWithUserId:@"testUserId" eventId:@"testEventId"]; 

    [mockHTTPClient verify]; 
} 

@end 

पिछले टिप्पणी करने के लिए बात यह है कि AFNetworking 2.0 संस्करण इसलिए जारी किया गया है उसका उपयोग अपनी आवश्यकताओं को शामिल किया गया है पर विचार है।

संबंधित मुद्दे