json - 测试用例 : SwiftHTTP library not making the HTTP call

标签 json swift unit-testing asynchronous xctestexpectation

重要事实

I forgot to mention an important factor in the question. I am running this in a TestCase. I think this issue has something to do with the TestCase not awaiting for async completionHandler to return

Alamofire迁移出来至 SwiftHTTP ,因为我发现这更容易。

在 SwiftHHTP 上,没有办法知道生成了什么 URL,它返回了什么错误。例如,我试图查看 opt.debugDescription变量,它返回了一些神秘的东西,比如 description String "<SwiftHTTP.HTTP: 0x60000007e540>"

我遵循的步骤

  • 我已经设置了YESAllow Arbitrary Loads .
  • 如果我粘贴 fullurl ->http://120.0.0.1:8080/myapi/Driver/getDriver?driver=2243&domain=4345&key=asdfasdf,iPhone 模拟器上的 Safari 会以正确的 JSON 响应.连catalina.out在我的 Mac 上运行的 tomcat 服务器以调试消息响应。

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

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

代码

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()

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

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

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

最佳答案

是的,默认情况下,单元测试不会等待 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?.fulfill 来实现 expectation

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


有一个有趣的blog post关于单元测试。 (参见“XCTestExpectation”部分)它是用旧的 Swift 语法编写的,但概念是相同的。

关于json - 测试用例 : SwiftHTTP library not making the HTTP call,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42481033/

相关文章:

javascript - react this.setState 问题

javascript - Express 正文解析器 : Unexpected token # in JSON at position 0

ios - 切换按钮静音(快速)

swift - 失败 : File name too longDomain: NSPOSIXErrorDomain xcode

python - 在 pydev 中使用 unittest 在 Python 中对整个项目层次结构进行单元测试

vb.net - CollectionAssert.AreEqual 通过但 CollectionAssert.AreEquivalent 失败?

java - 如何在 Java Web 服务中嵌入和绑定(bind) JSON 数据到 HTML 模板

java - Android - HTTP 响应的字符大小

ios - 按下按钮时打开 Facebook 应用程序页面。 swift 5

c# - 使用测试服务器的 .NET 6 E2E 测试在 TeamCity CI 上失败,但工作手动运行