TestCase:SwiftHTTP库没有进行HTTP调用

时间:2017-02-27 08:34:13

标签: json swift unit-testing asynchronous xctestexpectation

重要事实

  

我忘了在问题中提到一个重要因素。我在TestCase中运行它。我认为这个问题与TestCase有关,不等待异步completionHandler返回

Alamofire迁移到SwiftHTTP,因为我发现这更容易。

在SwiftHHTP上,无法知道生成了什么URL,返回了什么错误。例如,我试图看到opt.debugDescription变量,它返回了类似于描述字符串"<SwiftHTTP.HTTP: 0x60000007e540>"

的内容。

我遵循的步骤

  • 我已将YES设为Allow Arbitrary Loads
  • 如果我粘贴fullurl ->http://120.0.0.1:8080/myapi/Driver/getDriver?driver=2243&domain=4345&key=asdfasdf,iPhone模拟器上的Safari会使用正确的JSON进行响应。甚至在我的mac上运行的tomcat服务器上的catalina.out也会响应调试消息。

但是当我在Xcode下的测试用例中运行它时,下面的代码不打印任何调试打印。

  • - 1-&gt ;, - 2 - &gt;, - 3 - &gt;,没有打印出来。
  • 调试器断点也不止于此。

CODE

var getData = [String:String]()
       getData = ["domain": "4345",
           "driver" : "2343",
           "key" : "asdfasdf"]

       var urlComponents = URLComponents(string: fullURL)!
       var queryItems = [URLQueryItem]()
       queryItems = self.getData.map{ URLQueryItem(name : $0.0, value : $0.1) }
       urlComponents.queryItems = queryItems
       print("fullurl ->"+(urlComponents.url)!.absoluteString)

       do {
           let opt = try HTTP.GET((urlComponents.url)!.absoluteString)
                      opt.start { response in
               if let err = response.error {
                   print("--1-> error: \(err.localizedDescription)")
                   return //also notify app of failure as needed
               }
               print("--2--> opt finished: \(response.description)")
               self.responseData = response
           }
       } catch let error {
           print("--3--> got an error creating the request: \(error)")
       }    

修改

即使将代码更改为httpshttp://www.google.com,也会产生相同的结果。

let testComponents = URLComponents(string: "https://www.google.com")!
        URLSession.shared.dataTask(with: (testComponents.url)!, completionHandler: {
            (data, response, error) in
            if(error != nil){
                print("..1>..")
            }else{
                do{
                    print ("..2>.." )
                    let json = try JSONSerialization.jsonObject(with: data!, options:.allowFragments) as! [String : AnyObject]
                    self.responseData = json

                }catch let error as NSError{
                    print("..3>..")
                }
            }
        }).resume()

编辑1 试过here @Vivek的答案。

callWebService(url: (urlComponents.url)!.absoluteString)
.
.
func callWebService(url : String) {
.
.
let callURL = URL.init(string: url)

没有再打印,错误/ JSON,没有。

1 个答案:

答案 0 :(得分:3)

是的,单元测试默认情况下不会等待调用completionHandler。如果您在测试中调用异步函数,则不需要更改函数的代码,但需要更改测试的行为。

解决方案:XCTestExpectation

在您的测试类(XCTest的子类)中,添加以下属性:

var expectation: XCTestExpectation?

异步请求的测试函数基本上可能如下所示:

func testRequest() {
    expectation = expectation(description: "Fetched sites") //1

    //2
    some.asyncStuffWithCompletionHandler() {
        someData in
        if someData == nil {
            XCTestFail("no data") //3
            return
        }

        //looks like the request was successful
        expectation?.fulfill() //4
    }

    //5
    waitForExpectations(timeout: 30, handler: nil)
}

解释

  1. 这定义了您对测试代码的期望。但实际上,它并不重要,你添加的是什么描述。在运行测试时,它只是一个信息

  2. 这是completionHandler的函数,您正在调用

  3. 如果您想让测试在completionHanlder内失败,请致电XCTestFail()

  4. 如果completionHandler中的所有内容都按预期工作,请致电expectation完成expectation?.fulfill

  5. 以下是重要部分:这部分代码将在<{strong> completionHandler之前执行 !如果这将是函数的结束,则测试将停止。这就是为什么我们告诉测试要等到期望满足(或者经过一定时间)

  6. 关于单元测试有一个有趣的blog post。 (参见&#34; XCTestExpectation&#34;)它用旧的Swift语法编写,但概念是相同的。