问题描述
我正在尝试编写单元测试,当前正在尝试测试在viewDidLoad()
中接收到数据的viewController,该数据是在alamofire请求之后设置的.问题是,在我的测试函数中,当我检查成功请求后应该用10个元素填充的数组时,其值为0.我检查了测试中的viewDidLoad()
是否未执行,但是应该执行,因为当我只是将元素添加到请求之外的另一个数组中时,特定的测试有效.我想这与请求有关,到目前为止我还没有找到答案.
I'm trying to write Unit Tests and currently I try to test a viewController which received data in viewDidLoad()
, the data is set after a alamofire request. The problem is, that in my test function when I check the array which should be filled with 10 elements after the successful request, is 0. I've checked if viewDidLoad()
in the test is not executed, but it should be, because when I just add elements to another array, which is outside the request, the specific test works. I guess, it has something to do with the request and I didn't found answer so far.
这是代码(此带有解释的问题帮助我执行了viewController的viewDidLoad()):
Here is the code (this question with explanation, helped me to execute the viewDidLoad() of the viewController):
ViewController 简化:
ViewController simplified:
class ViewController: UIViewController {
var itemsFromRequest: [Int] = []
var itemsWithoutRequest: [Int] = []
override func viewDidLoad() {
super.viewDidLoad()
// array with 10 elements
itemsWithoutRequest = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
Alamofire.request(url: URLConvertible).responseJSON { response in
//...error handling, parsing etc.
// set array after successful response
self.itemsFromRequest = responseData
}
}
}
ViewControllerTests类:
The ViewControllerTests class:
class ViewControllerTests: XCTestCase {
var viewController: ViewController!
override func setUp() {
super.setUp()
let storyboard = UIStoryboard(name: "Main", bundle: nil)
viewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
// trigger viewDidLoad() of viewController
let _ = viewController.view
}
func testItemArraysHaveTenItems() {
// This is successful
XCTAssertEqual(viewController.itemsWithoutRequest.count, 10)
// This failed with error "XCTAssertEqual failed: ("0") is not equal to ("10")"
XCTAssertEqual(viewController.itemsFromRequest.count, 10)
}
}
为什么第二个断言失败了?
Why does the second Assertion failed?
推荐答案
问题
在第二个断言中,您期望异步加载的数据,但是您同步检查它们,并且在检查它们时,网络操作尚未完成,因此当然会失败.
Problem
On the second Assertion you expect data which are loaded asynchronously, but you check them synchronously and at the time you are checking for them, the network operation has not finished yet, so of course it is going to fail.
可以在iOS上使用 XCTestExpectation 进行异步测试.
Testing asynchronously is available on iOS using XCTestExpectation.
使用示例
Example of use
let testExpectation = expectation(description: "Asynchronous expectation")
let sut = SubjectUnderTest()
sut.executeAsynchronousOperation(completion: { (error, data) in
XCTAssertTrue(error == nil)
XCTAssertTrue(data != nil)
testExpectation.fulfill()
})
waitForExpectations(timeout: 5, handler: .none)
提示
要指出的另一件事是,测试网络操作并等待响应是一种不好的做法,您应该拦截网络请求并返回本地数据,而不是等待服务器的真实数据. (在GitHub上,有一个不错的框架可以在Swift中做到这一点: OHHTTPStubs )
这篇关于在viewDidLoad之后,未在测试中设置XCTest单元测试数据响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!