?????????????????????????? URL ??????????????? Alamofire ??????????
????????÷??????????parseResult????????????????????????????????
let testKey = "testKey"
let jsonDictWithError: [String: AnyObject] = ["code": 1]
let jsonDictWithoutData: [String: AnyObject] = ["code": 0]
let jsonDictWithData: [String: AnyObject] = ["testKey": "testValue"]
let manager = NetworkManager.defaultManager
let error = UMAError.errorWithCode(.Unknown)
func makeResultForFailureCaseWithError(error: NSError) -> Result<AnyObject?? NSError> {
return Result<AnyObject?? NSError>.Failure(error)
}
func makeResultForSuccessCaseWithValue(value: AnyObject) -> Result<AnyObject?? NSError> {
return Result<AnyObject?? NSError>.Success(value)
}
func testParseResult_failureCase_returnFailureCase() {
let result = makeResultForFailureCaseWithError(error)
let formattedResult = manager.parseResult(result?? responseKey: testKey)
XCTAssertTrue(formattedResult.isFailure)
}
func testParseResult_successCaseWithCode1_returnFailureCaseWithCode1() {
let result = makeResultForSuccessCaseWithValue(jsonDictWithError)
let formattedResult = manager.parseResult(result?? responseKey: testKey)
XCTAssertEqual(formattedResult.error!.code?? 1)
}
func testParseResult_successCaseWithoutData_returnFailureCaseWithTransformFailed() {
let result = makeResultForSuccessCaseWithValue(jsonDictWithoutData)
let formattedResult = manager.parseResult(result?? responseKey: testKey)
XCTAssertEqual(formattedResult.error!.code?? ErrorCode.TransformFailed.rawValue)
}
func testParseResult_successCaseWithData_returnTestValue() {
let result = makeResultForSuccessCaseWithValue(jsonDictWithData)
let formattedResult = manager.parseResult(result?? responseKey: testKey)
XCTAssertEqual(String(formattedResult.value!)?? "testValue")
}
???????????????????????????????????????????????????????parseResult????????????
?????????????????????????????????????????????????????????????????????????????????????????????????????????????????????漸???????????????????????????????????????????????????????????????????????????????????????????????????????????????????? fake ??α??????fake ??? stub ????????? mock ?????????????stub ?? mock ???????????????????????? mock ???ж??????????? stub ???ж???????仰???????????? fake ???ж??????????? mock????????? stub??
???????? Swift ?????????????????????????????? mock ????????????????????????Э?????????????????????????????????? fake ?????????????????Щ???????????????????? Alamofire ?????????ú???request???????????????????????Request????????????????????responseJSON?????????????????α?????????????????????
????Swift ????????? FP ?????????????????????????????е?????????——??????????????????????????????????????????????????????????????????? fake function??α????????????????……???????????????????? NetworkManager ????????????????????????α??????α????
typealias NetworkCompletionHandler = Result<AnyObject?? NSError> -> Void
typealias NetworkRequest = (Alamofire.Method??
URLStringConvertible??
[String : AnyObject]???
Alamofire.ParameterEncoding??
[String : String]?) -> Responsable
protocol Responsable: Cancellable {
func responseJSON(queue queue: dispatch_queue_t???
options: NSJSONReadingOptions??
completionHandler: Alamofire.Response<AnyObject?? NSError> -> Void) -> Self
}
extension Alamofire.Request: Responsable {}
class NetworkManager {
// static ??????? lazy Ч???????? let ??????????
static let defaultManager = NetworkManager(request: Alamofire.request)
let request: NetworkRequest
init(request: NetworkRequest) {
self.request = request
}
/**
Fetch raw object
- parameter api:              API address
- parameter method:           HTTP method?? default = POST
- parameter parameters:       Request parameters?? default = nil
- parameter responseKey:      Key of target value?? use '.' to get nested objects?? e.g. "data.vehicle_list"
- parameter jsonArrayHandler: Handle result with raw object
- returns: Optional request object which is cancellable.
*/
func fetchDataWithAPI(api: API??
method: Alamofire.Method = .POST??
parameters: [String: String]? = nil??
responseKey: String??
networkCompletionHandler: NetworkCompletionHandler) -> Cancellable? {
guard let url = api.url else {
printLog("URL Invalid: \(api.rawValue)")
return nil
}
return request(method?? url?? parameters?? .URL?? nil).responseJSON(queue: nil?? options: .AllowFragments) {
networkCompletionHandler(self.parseResult($0.result?? responseKey: responseKey))
}
}
// ...
}
????????????????μ?????NetworkRequest????????????????????? Alamofire ?е???????request?????????????????defaultManager?????????????????????????????????NetworkRequest???????????????????????NetworkManager?С?????????????Responsable??Э?飬?????extension ??????? Alamofire ?е?Request?????Э?飬???Э????????????????????????????Request?? fake ????
???????????????????д??????????
func testFetchDataWithAPI_requestWithMock_resultWithErrorCode666() {
struct MockResponse: Responsable {
func responseJSON(queue queue: dispatch_queue_t???
options: NSJSONReadingOptions??
completionHandler: Alamofire.Response<AnyObject?? NSError> -> Void)
-> MockResponse {
let unknowError = UMAError.errorWithCode(666?? description: "error for test")
let result = Result<AnyObject?? NSError>.Failure(unknowError)
let response = Alamofire.Response(request: nil?? response: nil?? data: nil?? result: result)
completionHandler(response)
return self
}
func cancel() {}
}
let request: NetworkRequest = {_?? _?? _?? _?? _ in return MockResponse() }
let testableManager = NetworkManager(request: request)
testableManager.fetchDataWithAPI(.PostCategory?? responseKey: "data") {
XCTAssertEqual($0.error!.code?? 666)
}
}