ios - Xcode:单元测试时 URL 共享 session 未运行

标签 ios swift xcode unit-testing

我制作了一个简单的应用程序,可以将数据添加到数据库,然后检索它。创建单元测试时,URLSession.Shared.dataTask 似乎未运行。我可以通过我设置的打印语句的输出看到这一点。下面是我的代码:

func addChild(childName:String,dob:String,number1:String,number2:String,parentNum:String,parentPass:String,notes:String){

    //url to php file
    let url = NSURL(string:"http://localhost/addChild.php")

    //request to this file
    let request = NSMutableURLRequest(url: url as! URL)

    //method to pass data to this file
    request.httpMethod = "POST"

    //body to be appended to url
    let body = "childName=\(childName)&dateOfBirth=\(dob)&contact1=\(number1)&contact2=\(number2)&parentAccNum=\(parentNum)&parentAccPass=\(parentPass)&notes=\(notes)"
    request.httpBody = body.data(using: String.Encoding.utf8)
    print("a")
    //launching the request
    URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { (data:Data?, response:URLResponse?, error:Error?) in
        print("b")
        if (error == nil){
            print("c")
            //send request
            //get main queue in code process to communicate back to user interface
            DispatchQueue.main.async(execute: {

                do{
                    //get json result
                    let json = try JSONSerialization.jsonObject(with: data!,options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
                    print("d")
                    //assigning json to parseJSON in guard/secure way
                    //checking whether the parsing has worked
                    guard let parseJSON = json else{
                        print("Error while parsing")
                        return
                    }

                    //get id from parseJSON dictionary
                    let id = parseJSON["id"]

                    //if there is some id value
                    if id != nil{
                        print(parseJSON)
                        self.success = true
                        print("success")
                    }
                }
                catch{
                    print("Caught an error:\(error)")
                }


            } )
        }
            //if unable to proceed request
        else{
            print("Error:\(error)")
        }
        //launch prepared session
    }).resume()
}

下面是我的单元测试脚本:

import XCTest
@testable import computerScienceCoursework


class addChildTest: XCTestCase {
    //Setting up the values of the text fields
    var testChildName:String = "Test name"
    var testDOB:String = "99/99/99"
    var testContact1:String = "00000000000"
    var testContact2:String = "11111111111"
    var testParAccNum:String = "-1"
    var testParAccPass:String = "Password"
    var testNotes:String = "Insert notes here"



    var newChild = AddChildController()

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.


        }

    override func tearDown() {
    // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testAddChildIsWorking(){
        //Assigning the values to the text fields
        newChild.addChild(childName: testChildName,dob: testDOB,number1: testContact1,number2: testContact2,parentNum: testParAccNum,parentPass: testParAccPass,notes: testNotes)
        XCTAssert(newChild.success == true)
    }

}

最佳答案

这里的问题是您不知道异步任务何时完成以及成功属性何时更新。 您的问题有一些可能的解决方案,其中之一是向您的方法添加完成处理程序。

func addChild(childName:String,dob:String,number1:String,number2:String,parentNum:String,parentPass:String,notes:String, completion: (Bool) -> Void){
    //url to php file
    let url = NSURL(string:"http://localhost/addChild.php")

    //request to this file
    let request = NSMutableURLRequest(url: url as! URL)

    //method to pass data to this file
    request.httpMethod = "POST"

    //body to be appended to url
    let body = "childName=\(childName)&dateOfBirth=\(dob)&contact1=\(number1)&contact2=\(number2)&parentAccNum=\(parentNum)&parentAccPass=\(parentPass)&notes=\(notes)"
    request.httpBody = body.data(using: String.Encoding.utf8)
    print("a")
    //launching the request
    URLSession.shared.dataTask(with: request as URLRequest, completionHandler: { (data:Data?, response:URLResponse?, error:Error?) in
        print("b")
        if (error == nil){
            print("c")
            //send request
            //get main queue in code process to communicate back to user interface
            DispatchQueue.main.async(execute: {

                do{
                    //get json result
                    let json = try JSONSerialization.jsonObject(with: data!,options: JSONSerialization.ReadingOptions.mutableContainers) as? NSDictionary
                    print("d")
                    //assigning json to parseJSON in guard/secure way
                    //checking whether the parsing has worked
                    guard let parseJSON = json else{
                        print("Error while parsing")
                        completion(false)
                        return
                    }

                    //get id from parseJSON dictionary
                    let id = parseJSON["id"]

                    //if there is some id value
                    if id != nil{
                        print(parseJSON)
                        self.success = true
                        print("success")
                        completion(true)
                    }
                }
                catch{
                    print("Caught an error:\(error)")
                    completion(false)
                }

            } )
        }
            //if unable to proceed request
        else{
            print("Error:\(error)")
            completion(false)

        }
        //launch prepared session
    }).resume()
}

然后在您的测试方法中您可以使用该方法。

        func testAddChildIsWorking()
        {
            let asyncExpectation = expectationWithDescription("addChildIsWorkingFunction")

            newChild.addChild(childName: testChildName, dob: testDOB, number1: testContact1,
            number2: testContact2, parentNum: testParAccNum, parentPass: testParAccPass, notes: testNotes) { (success) in

                 asyncExpectation.fulfill()

            }

            self.waitForExpectationsWithTimeout(10) { error in

                 XCTAssert(newChild.success == true)
             }       
         }

waitForExpectationWithTimeout 正在等待直到完成被触发或发生超时。通过这种方式,您可以测试您的异步代码。 有关更多信息,请查看此 link

希望对您有所帮助。

关于ios - Xcode:单元测试时 URL 共享 session 未运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40763611/

相关文章:

ios - 毫秒至今

objective-c - 如何知道哪些部分或行在 listnewcontroller 上显示或可见

ios - 如何在 NSMutableArray 中快速将对象添加为 NSMutableArray

objective-c - 如何通过键删除NSMutableArray对象?

ios - 如何在静态函数中使用 UITapGestureRecognizer 向标签添加点击功能

iphone - 使用 Xcode 查找错误 - 尝试插入 nil 值

ios - 检测 EKStore 是否允许创建日历

iOS:如果当前正在刷行,如何防止表更新?

ios - 使用图像动态调整表格 View 单元格的大小

ios - CALayer 委托(delegate)仅在使用 Swift 时偶尔调用