2014-04-29 12 views
5

मैं एक कक्षा का परीक्षण करने की कोशिश कर रहा हूं जो XCTest का उपयोग कर XCode 5 में AFNEtworking का उपयोग करता है। मेरे पास यह मुद्दा है कि मेरे AFHTTPRequestOperation के लिए समापन ब्लॉक कभी निष्पादित नहीं किए जा रहे हैं। मुझे लगता है कि यह एक्सकोड और यूनिटवर्किंग की प्रेषण कतार चलाने वाले एक्सकोड के बीच कुछ डिस्कनेक्ट है। निम्नलिखित टेस्ट केस पास हो जाते हैं लेकिन पूरा होने वाले ब्लॉक में एनएसएलओजी कथन कभी नहीं पहुंचते हैं (कोई लॉग आउटपुट नहीं है और इन कथनों पर कोई ब्रेकपॉइंट नहीं पकड़ा जाता है)। एक ही कोड एक इकाई परीक्षण के बाहर काम करता है। क्या किसी को पता है कि इस मुद्दे के आसपास कैसे काम करना है? मैं वास्तविक अनुरोधों का नकल करने के लिए नोकिला का उपयोग कर रहा हूं, परिणाम वास्तविक प्रतिक्रियाओं को फिर से शुरू करने वाले वास्तविक सर्वर का उपयोग कर समान है?AFNetworking 2.0 और यूनिट टेस्ट

संपादित परीक्षण असफल और लॉग

- (void)setUp 
{ 
    [super setUp]; 
    // Put setup code here. This method is called before the invocation of each test method in the class. 



    [[LSNocilla sharedInstance] start]; 

    stubRequest(@"POST", @"http://www.example.com/module/api/ping"). 
    andReturn(200). 
    withHeaders(@{@"Content-Type": @"application/json"}). 
    withBody(@"{\"success\":true}"); 

    stubRequest(@"GET", @"http://www.example.com/module/api/ping?testkey=testval"). 
    andReturn(200). 
    withHeaders(@{@"Content-Type": @"application/json"}). 
    withBody(@"{\"success\":true}"); 
} 

- (void)tearDown 
{ 
    // Put teardown code here. This method is called after the invocation of each test method in the class. 
    [super tearDown]; 

    [[LSNocilla sharedInstance] stop]; 
    [[LSNocilla sharedInstance] clearStubs]; 
} 

- (void)testSanity 
{ 
    AFSecurityPolicy *policy = [[AFSecurityPolicy alloc] init]; 
    //[policy setAllowInvalidCertificates:YES]; 

    AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.example.com/module/api/ping"]]; 
    //manager.operationQueue = [NSOperationQueue mainQueue]; 
    [manager setSecurityPolicy:policy]; 


    manager.requestSerializer = [AFJSONRequestSerializer serializer]; 
    manager.responseSerializer = [AFJSONResponseSerializer serializer]; 


    __block id resObj = nil; 
    __block id resError = nil; 

    AFHTTPRequestOperation *req = [manager POST:@"http://www.example.com/module/api/ping" 
            parameters:[NSDictionary dictionaryWithObject:@"testval" forKey:@"testkey"] 
             success:^(AFHTTPRequestOperation *operation, id responseObject) { 

              NSLog(@"Response: %@", responseObject); 
              resObj = responseObject; 
              return; 

             } 
             failure:^(AFHTTPRequestOperation *operation, NSError *error) { 

              NSLog(@"Error: %@", error); 
              resError = error; 
              return; 
             }]; 
    [req waitUntilFinished]; 

    NSLog(@"req.status: %d", req.response.statusCode); 
    NSLog(@"req.responseObj: %@", req.responseObject); 
    XCTAssertTrue(req.isFinished); 
    NSLog(@"resObj: %@", resObj); 
    NSLog(@"resError: %@", resError); 
    XCTAssertEqual([[req.responseObject objectForKey:@"success"] boolValue], YES); 

    XCTAssertEqual([[resObj objectForKey:@"success"] boolValue], YES); 
} 

कंसोल आउटपुट

 
Test Case '-[AppSupportTests testSanity]' started. 
2014-04-29 16:45:07.424 xctest[72183:303] req.status: 200 
2014-04-29 16:45:07.424 xctest[72183:303] req.responseObj: { 
    success = 1; 
} 
2014-04-29 16:45:07.424 xctest[72183:303] resObj: (null) 
2014-04-29 16:45:07.425 xctest[72183:303] resError: (null) 
/Users/jlujan/Code/AppSupport/AppSupportTests/AppSupportTests.m:114: error: -[AppSupportTests testSanity] : (([[resObj objectForKey:@"success"] boolValue]) equal to (__objc_yes)) failed: ("NO") is not equal to ("YES") 
Test Case '-[AppSupportTests testSanity]' failed (0.003 seconds). 
+0

पृष्ठभूमि ऑपरेशन समाप्त होने के बाद शायद यह 'WaitUntilFinished' को कॉल कर रहा है, लेकिन कॉलबैक कहने से पहले यह होगा। आप ['सेमफोर की] (https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html#//apple_ref/doc/uid/TP40008079-CH2 का उपयोग करने का प्रयास कर सकते हैं -SW38) [प्रतीक्षा करें] (http://goo.gl/lepGmc) जब तक आपके पास [सिग्नल] नहीं है (https://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference .html # // apple_ref/doc/uid/TP40008079-CH2-SW39) – Rich

+1

असीमित परीक्षण के लिए मैं [Expecta] (https://github.com/specta/expecta/) को अनुशंसा करता हूं। फिर आप 'उम्मीद ([[req.responseObject ऑब्जेक्टफोरकी: @ "सफलता"] boolValue] जैसी चीजें कर सकते हैं)। Will.beTruthy();' (हालांकि मैं 'beTruthy' वाक्यविन्यास पर उत्सुक नहीं हूं!)। आपको बस यह सुनिश्चित करना होगा कि आप एक उपयुक्त टाइमआउट सेट करें [[एक्स्पेक्टा सेटएसिंक्रोनसटेस्टटाइमआउट: 15]; // सेकंड्स – Rich

+0

यह सुनिश्चित करने के लिए कि मेरा वास्तविक कोड इसका कारण नहीं था, यह केवल एक सैनिटी चेक था। यहां सेमफोर उदाहरण का उपयोग करना http://stackoverflow.com/questions/20476957/afnetworking-2-waituntilfinished-not-working, यह हमेशा के लिए लटकता है। किसी भी तरह से, मैं अपने वास्तविक कोड में सेमफोर विधि का उपयोग नहीं कर सकता। – jlujan

उत्तर

2
टिप्पणी में

चर्चा के अनुसार हम चाहते हैं कि waitUntilFinished is once the background operation is complete पाया ब्लॉक में सेट वार्स बनाने के लिए, और यदि ऐसा नहीं होता पूरा होने के बाद तक प्रतीक्षा करें।

असीमित परीक्षण के लिए एक बेहतर ढांचा है - Expecta
फिर कॉल करने के बजाय:

XCTAssertTrue(req.isFinished); 
XCTAssertEqual([[resObj objectForKey:@"success"] boolValue], YES); 

आप कर सकते हैं:

expect(req.isFinished).will.beTruthy(); 
expect([[resObj objectForKey:@"success"] boolValue]).will.beTruthy(); 

वहाँ lots of other matchers हैं, बस सुनिश्चित करें कि आप अपने +setUp विधि में +[Expecta setAsynchronousTestTimeout:] साथ timeout सेट किया है।

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