2015-12-14 58 views
2

我想寫一個數據對象(Realm)使用Alamofire刷新它的屬性的方法。但我無法弄清楚如何進行單元測試。在單元測試中等待Alamofire

import Alamofire 
import RealmSwift 
import SwiftyJSON 

class Thingy: Object { 

    // some properties 
    dynamic var property 

    // refresh instance 
    func refreshThingy() { 
    Alamofire.request(.GET, URL) 
     .responseJSON { 
      response in 
       self.property = response["JSON"].string 
     } 
    } 
} 

在我的單元測試中,我想測試Thingy可以從服務器正確刷新。

import Alamofire 
import SwiftyJSON 
import XCTest 
@testable import MyModule 

class Thingy_Tests: XCTestCase { 

func testRefreshThingy() { 
    let testThingy: Thingy = Thingy.init() 
    testThingy.refreshProject() 
    XCTAssertEqual(testThingy.property, expected property) 
} 

我該如何正確設置單元測試?

回答

9

使用XCTestExpectation等待異步過程,例如:

func testExample() { 
    let e = expectation(description: "Alamofire") 

    Alamofire.request(urlString) 
     .response { response in 
      XCTAssertNil(response.error, "Whoops, error \(response.error!.localizedDescription)") 

      XCTAssertNotNil(response, "No response") 
      XCTAssertEqual(response.response?.statusCode ?? 0, 200, "Status code not 200") 

      e.fulfill() 
    } 

    waitForExpectations(timeout: 5.0, handler: nil) 
} 

在你的情況,如果你要測試你的異步方法,你必須提供一個完成處理程序refreshThingy

class Thingy { 

    var property: String! 

    func refreshThingy(completionHandler: ((String?) -> Void)?) { 
     Alamofire.request(someURL) 
      .responseJSON { response in 
       if let json = response.result.value as? [String: String] { 
        completionHandler?(json["JSON"]) 
       } else { 
        completionHandler?(nil) 
       } 
     } 
    } 
} 

然後你就可以測試Thingy

func testThingy() { 
    let e = expectation(description: "Thingy") 

    let thingy = Thingy() 
    thingy.refreshThingy { string in 
     XCTAssertNotNil(string, "Expected non-nil string") 
     e.fulfill() 
    } 

    waitForExpectations(timeout: 5.0, handler: nil) 
} 

坦率地說,使用完成處理程序的這種模式可能是您想要的refreshThingy中的任何一種,但是如果您不想提供完成處理程序,我會將其設置爲可選項。

+0

這正是我所期待的。感謝Rob! –

+0

漂亮的尾隨閉包語法,而不是'thingy.refreshThingy {(string:String?) - >()in' – lazi74

+0

Rob,爲什麼你在'timeout'中放置'5.0'秒而不是'1.0'? –