2015-02-17 1 views
2

У меня есть следующий код, который я хочу создать для модульного теста. Я хочу, чтобы проверить, если self.response не нольXcode - блок тестирует сетевой вызов

- (void)downloadJson:(NSURL *)url { 
    // Create a download task. 
    NSURLSessionDataTask *task = [[NSURLSession sharedSession] 
     dataTaskWithURL:url 
     completionHandler:^(NSData *data, NSURLResponse *response, 
          NSError *error) { 
     if (!error) { 
      NSError *JSONError = nil; 
      NSDictionary *dictionary = 
       [NSJSONSerialization JSONObjectWithData:data 
               options:0 
               error:&JSONError]; 
      if (JSONError) { 
      NSLog(@"Serialization error: %@", JSONError.localizedDescription); 
      } else { 
      NSLog(@"Response: %@", dictionary); 
      self.response = dictionary; 
      } 
     } else { 
      NSLog(@"Error: %@", error.localizedDescription); 
     } 
     }]; 
    // Start the task. 
    [task resume]; 
} 

то, что я до сих пор

- (void)testDownloadJson { 

    XCTestExpectation *expectation = 
     [self expectationWithDescription:@"HTTP request"]; 
    [self.vc 
     downloadJson:[NSURL URLWithString:@"a json file"]]; 

    [self waitForExpectationsWithTimeout:5 
           handler:^(NSError *error) { 
           // handler is called on _either_ success or 
           // failure 
           if (error != nil) { 
            XCTFail(@"timeout error: %@", error); 
           } else { 
            XCTAssertNotNil(
             self.vc.response, 
             @"downloadJson failed to get data"); 
           } 
           }]; 
} 

Но, конечно, это не правильно. Интересно, может ли кто-нибудь помочь мне понять, как написать этот тест.

Благодаря

+1

сделано. Еще раз спасибо. – user2812463

ответ

4

downloadJson ли не обеспечивает какой-то обработчик завершения, блок, который может быть вызван, когда асинхронный вызов заканчивается? См. How do I unit test HTTP request and response using NSURLSession in iOS 7.1? на примере того, как обычно используется XCTestExpectation.

Обычно вы размещаете [expectation fulfill] внутри обработчика завершения, так что waitForExpectationsWithTimeout знает, что это удалось.

Откровенно говоря, наличие блока завершения для вашего метода downloadJson, вероятно, будет полезным, так или иначе, поэтому вы можете добавить это.

- (void)downloadJson:(NSURL *)url completionHandler:(void (^)(NSDictionary *responseObject, NSError *error))completionHandler { 
    NSURLSessionDataTask *task = [[NSURLSession sharedSession] dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { 
     if (data) { 
      NSError *JSONError = nil; 
      NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&JSONError]; 
      if (dictionary) { 
       // self.response = dictionary; // personally, I wouldn't do this here, but just pass this back in the completion handler 
       if (completionHandler) { 
        dispatch_async(dispatch_get_main_queue(), ^{ 
         completionHandler(dictionary, nil); 
        }); 
       } 
      } else { 
       // NSLog(@"Serialization error: %@", JSONError.localizedDescription); // I'd let caller do whatever logging it wants 
       if (completionHandler) { 
        dispatch_async(dispatch_get_main_queue(), ^{ 
         completionHandler(nil, JSONError); 
        }); 
       } 
      } 
     } else { 
      if (completionHandler) { 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        completionHandler(nil, error); 
       }); 
      } 
      // NSLog(@"Error: %@", error.localizedDescription); // I'd let caller do whatever logging it wants 
     } 
    }]; 

    [task resume]; 
} 
+1

именно то, что я искал, я отредактировал исходный пост с правильным способом для справок в будущем. – user2812463

2

следуя по ссылке, размещенной Робом, теперь у меня есть это, и это работает

- (void)downloadJson:(NSURL*)url andCallback:(void (^)(NSDictionary*))callback 
{ 
    // Create a download task. 
    NSURLSessionDataTask* task = [[NSURLSession sharedSession] dataTaskWithURL:url 
                  completionHandler:^(NSData* data, 
                        NSURLResponse* response, 
                        NSError* error) { 
             if (!error) 
             { 
              NSError *JSONError = nil; 

              NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:data 
                            options:0 
                             error:&JSONError]; 
              if (JSONError) 
              { 
               NSLog(@"Serialization error: %@", JSONError.localizedDescription); 
              } 
              else 
              { 
               NSLog(@"Response: %@", dictionary); 
               self.response = dictionary; 
               callback(self.response); 
              } 
             } 
             else 
             { 
              NSLog(@"Error: %@", error.localizedDescription); 
             } 
                  }]; 
    // Start the task. 
    [task resume]; 
} 

и испытание

- (void)testDownloadJson 
{ 
    XCTestExpectation* expectation = [self expectationWithDescription:@"HTTP request"]; 

    [self.vc downloadJson:[NSURL URLWithString:@"a json file"] andCallback:^(NSDictionary* returnData) { 
     XCTAssertNotNil(returnData, @"downloadJson failed to get data"); 
     [expectation fulfill]; 
    }]; 

    [self waitForExpectationsWithTimeout:10.0 handler:nil]; 
}