对在Swift中使用REST调用的方法进行单元测试

Sea*_*iss 2 rest json unit-testing swift

首先,我要说明我仍不熟悉我要尝试做的事情,但是努力变得更好!

我正在为一个正在编写单元测试的项目工作,但是在解决问题上遇到了一些麻烦。

我正在测试的方法利用RESTAPI调用来验证用户凭据。我不确定最好的单元测试方法是什么。

这是我要进行单元测试的方法:

@IBAction func loginBtnActivate(sender: UIButton) {
    let enteredEmail: String = emailField.text!
    let enteredPassword: String = passwordField.text!
    let testInfo:[String: AnyObject] = ["User": enteredEmail, "Password": enteredPassword]
    RestApiManager.sharedInstance.postLogin(testInfo) { (json, statusCode) in
        if statusCode == 200 {
            let AuthToken: TokenObject = (TokenObject(json: json))
            try! self.keychain.set(AuthToken.Authorization, key:"Authorization")
            try! self.keychain.set(AuthToken.LifeTime, key: "LifeTime")
            try! self.keychain.set(AuthToken.UUID, key: "UUID")
             NSOperationQueue.mainQueue().addOperationWithBlock {
                self.performSegueWithIdentifier("loginToMyHealth", sender: nil)
            }
        } else if statusCode == 401 {
            self.incorrectLoginAlert()
        } else if statusCode == 503 {
            print("Service Unavailable Please Try Again Later")
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我目前正在采用的方法是:

 func testLoginInfoMatchesDataOnServer(){
    let enteredEmail: String = "user"
    let enteredPassword: String = "password"
    let testInfo:[String: AnyObject] = ["User": enteredEmail, "Password": enteredPassword]
    RestApiManager.sharedInstance.postLogin(testInfo) { (json, statusCode) in
    XCTAssert(statusCode == 200, "statusCode is not matching the server data")
}
Run Code Online (Sandbox Code Playgroud)

我只是在验证Rest调用是否成功以及凭据是否与JSON匹配。XCTAssert调用似乎无法正常工作。无论我将第一个参数设置为什么,XCTAssert都不会影响测试是否成功。

例如,如果我放:

XCTAssert(false, "statusCode is not matching the server data")
Run Code Online (Sandbox Code Playgroud)

无论我做什么,该测试仍将通过。如果我将Assert函数放在方括号之外,则变量“ statusCode”似乎不在范围内,因此我陷入了

使用未解决的标识符“ statusCode”。

   func testLoginInfoMatchesDataOnServer(){
let enteredEmail: String = "user"
let enteredPassword: String = "password"
let testInfo:[String: AnyObject] = ["User": enteredEmail, "Password": enteredPassword]
RestApiManager.sharedInstance.postLogin(testInfo) { (json, statusCode) in
}
XCTAssert(statusCode == 200, "statusCode is not matching the server data")
}
Run Code Online (Sandbox Code Playgroud)

我正在寻找本指南以寻求帮助。.这将是我尝试做的更好的方法吗?

http://roadfiresoftware.com/2016/06/how-do-you-unit-test-rest-calls-in-swift/

同样,我对某些核心概念的理解可能会完全消失,因此,我非常感谢您在这里提出的建议!

提前致谢!

肖恩·W。

kat*_*tch 5

您的代码的前几个问题

function test(){    
    RestApiManager.sharedInstance.postLogin(testInfo) { (json, statusCode) in

    }//PostLogin call ends
    XCTAssert(statusCode == 200, "statusCode is not matching the server data") // Here StatusCode is not accessible as outside the block
}// end function
Run Code Online (Sandbox Code Playgroud)

如果要使用状态码,则应该执行

function test(){    
    RestApiManager.sharedInstance.postLogin(testInfo) { (json, statusCode) in
        XCTAssert(statusCode == 200, "statusCode is not matching the server data") // Here StatusCode is accessible inside the block
    }//PostLogin call ends
}// end function
Run Code Online (Sandbox Code Playgroud)

但这将失败,因为您需要等待响应。可以使用

waitForExpectationsWithTimeout(5)

所以称呼它的正确方法是-

function test(){    
    let URL = NSURL(string: "http://google.com/")!
    let expectation = expectationWithDescription("GET \(URL)")
    RestApiManager.sharedInstance.postLogin(testInfo) { (json, statusCode) in
        XCTAssert(statusCode == 200, "statusCode is not matching the server data") // Here StatusCode is accessible inside the block
        expectation.fulfill()
    }//PostLogin call ends
    waitForExpectationsWithTimeout(5){ error in 
        if let error = error {
            print("Error: \(error.localizedDescription)")
        }
    }//Wait block end
}// end function
Run Code Online (Sandbox Code Playgroud)

重要的几行是

Expectation.fulfill()//告诉过程已完成

waitForExpectationsWithTimeout(5){} //告诉等待5秒或抛出错误

欲了解更多信息