- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我尝试熟悉 TDD。如何测试异步的 URLSession 调用?哪个 XCAssert 更适合在哪个阶段使用?
我的第一个想法是创建一个函数,其中包含 URLSession,并在该函数中将 bool 标志设置为 true,然后在 XCAssertTrue 中对其进行测试。或者另一个想法是在调用包含 USLSession 代码的函数后同步返回假数据。
最佳答案
好问题。我认为它可以分为两部分,第一部分是关于如何使用 XCTest
测试异步代码,第二部分是关于您建议的策略。
异步代码的问题是它在与测试不同的线程上运行,这导致测试在异步调用之后继续进行,并在异步调用完成之前完成。
XCTest 框架提供了一个专为此用例构建的 waitForExpectationsWithTimeout:handler
函数。它允许您等待异步调用完成,然后才检查其结果。
你可以这样使用它:
import XCTest
@testable import MyApp
class CallbackTest: XCTestCase {
func testAsyncCalback() {
let service = SomeService()
// 1. Define an expectation
let expectation = expectationWithDescription("SomeService does stuff and runs the callback closure")
// 2. Exercise the asynchronous code
service.doSomethingAsync { success in
XCTAssertTrue(success)
// Don't forget to fulfill the expectation in the async callback
expectation.fulfill()
}
// 3. Wait for the expectation to be fulfilled
waitForExpectationsWithTimeout(1) { error in
if let error = error {
XCTFail("waitForExpectationsWithTimeout errored: \(error)")
}
}
}
}
您可以在 this blog post 中阅读有关该方法的更多信息。 完全公开,我写的。
现在,关于您的建议:
My first thought was to create a function, that has URLSession inside it, and inside this function set bool flag to true and then test it in
XCAssertTrue
.
好主意。这是测试是否实际调用异步回调的好方法。唯一要记住的是测试需要等待异步调用运行,否则它总是会失败。
使用上面的技术你可以写:
let service = SomeService()
var called = false
let expectation = expectationWithDescription(
"The callback passed to SomeService is actually called"
)
service.doSomethingAsync { _ in
called = true
expectation.fulfill()
}
waitForExpectationsWithTimeout(1) { error in
if let error = error {
XCTFail("waitForExpectationsWithTimeout errored: \(error)")
}
XCTAssertTrue(called)
}
Or another thought was to return fake data synchronously after calling function which contains
URLSession
code.
这是另一个好主意。将软件分解成只做一件事的组件,对它们进行彻底的隔离测试,最后通过一些强调快乐和最常见的失败路径的集成测试来测试它们是否一起工作。
既然您提到了 URLSession
,我想就涉及网络的单元测试代码留下警告说明。在单元测试中进行真实的网络调用通常不是一个好主意。事实上,它将测试绑定(bind)到网络可用并返回预期结果的事实,同时也使它们变慢。
在单元级别,我们希望我们的测试是独立的、确定的和快速的(更多关于这个 here )。使用网络与这些目标不一致。
避免访问网络的一个好方法是对其进行 stub ,方法是将 URLSession
包装到协议(protocol)中,然后在测试中使用符合它的伪造,或者使用类似 OHHTTPStubs 的库。 This post 更详细,再次全面披露,我也写了这个。
希望这对您有所帮助。对异步代码进行单元测试并非易事,您应该耐心等待并在出现问题时不断提问 :)
关于Swift TDD 和异步 URLSession - 如何测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40330692/
共享 URLSession 和默认配置的 URLSession 有什么区别? 在我的应用程序中,我使用 URLSession.shared 向服务器发送请求。现在我尝试将其更改为 URLSession
我有一个URLSessionDataDelegate来将图片上传到服务器,以下是其中的一部分。 当我选择要上传的图像时,URLSession 会立即初始化。 但是,如果用户点击上传按钮并且没有互联网连
Swift 5 引入了新的 Result 类型来处理异步函数的结果。我想知道如何将这种新的结果类型用于 URLSession。 I have this following code. func get
在后台 session 中,对于使用 https 的应用<>服务器通信,以下方法的相当轻松的实现有什么区别,或根本没有 ? func urlSession(_ session: URLSessio
我正在尝试使用 Swift 向带有一些 JSON 数据的 php 脚本发出 POST 请求。当我运行以下代码时,我的应用程序崩溃并且没有信息记录到控制台。 if let jsonData = try?
我有一个用于对服务器进行身份验证的客户端代码(已实现服务器,以便在成功时我收到重定向网址),并且想要检查状态代码是否为 302。但是请求会自动重定向,响应结果是200。那么问题是如何防止自动重定向?
我正在对 URLSession 使用方法调配,下面是我的调配方法。我不确定为什么应用程序在执行 @escaping 的完成处理程序时在目标应用程序中崩溃。请帮助我。 @objc func mytest
使用 URLSessionDownloadTask。有没有办法使用委托(delegate) didwritedata 获取多个文件下载的总体进度?在一个 我有所有文件的预期大小,现在我需要所有当前任务
我刚刚遇到的事情完全改变了我对 iOS 中 URLSession 缓存的印象。 我们正在触及一个只被触及过一次的端点。 重新启动应用程序不会再次到达端点。 删除应用会导致它再次到达端点...但只有一次
我正在使用 URLSession 和一项名为 Backendless 的服务。 Backendless 与 Parse 非常相似。 Backendless 有一个消息服务,可以让你发送电子邮件。我在我
我已经使用适合 URLSession 完整回调签名的方法定义了自己的类,例如。 G。 (数据?、响应?、错误?)-> 无效。该方法包含用于处理响应的通用逻辑,例如。 G。检查数据,解析数据等现在我想对
我正在尝试使用一段在 Xcode playground 文件中工作的代码从本地服务器获取一些数据: URLSession.shared.dataTask(with: url!, comp
我正在使用一个实际上是为 swift 2 编写的函数。我已经为 swift 3 做了调整。但我不断收到错误: URLSession' produces '()', not the expected c
我正在尝试在我的 iOS 应用程序中与我公司的 API 进行通信。我使用的是标准 URLSession。 API 会自动负载平衡并重定向到不同的服务器,因此我实现了处理重定向的 URLSessionD
为每个网络请求创建一个新的 URLSession 是否会占用大量资源? 一些背景: 我正在开发一个用于发出网络请求的库。我正在尝试添加一项功能,允许将结果下载到一个文件中,该文件也会报告其进度。为此,
我目前正在使用基于此教程的代码 http://sweettutos.com/2015/11/06/networking-in-swift-how-to-download-a-file-with-nsu
我有一个从 viewDidLoad 触发的 URLSession。它返回包含图像 URL 的 JSON。因此,为了获得该图像,我从第一个 URLSession 的完成 block 调用的 JSON 解
尝试使用 Swift jSon 解码器解析 json 时出现类型不匹配错误。 我只是找不到正常解析它的方法。 错误: typeMismatch(Swift.String, Swift.Decoding
我正在查看一个用 Swift 4 编写的 iOS 应用程序。它有一个使用 URLSession 的相当简单的网络层,但是该应用程序没有单元测试,在我开始重构之前,我很想通过引入一些来解决这个问题测试。
我正在使用 URLSession 和 downloadTask 在前台下载文件。下载比预期慢得多。我发现的其他帖子解决了后台任务的问题。 let config = URLSessionConfigur
我是一名优秀的程序员,十分优秀!