完成处理程序不返回任何内容,即使它看起来像在单步执行时
Posted
技术标签:
【中文标题】完成处理程序不返回任何内容,即使它看起来像在单步执行时【英文标题】:completion handler not returning anything even though its looks like it is when stepping through it 【发布时间】:2018-03-13 18:17:42 【问题描述】:这里是函数,它使用了 Operation(NSOperation):
typealias ResultType = Result<Data>
typealias CompletionType = (ResultType) -> ()
public var onCompletion: CompletionType?
internal func getNetworkConnection(urlRequest: URLRequest, completionHandler: @escaping CompletionType)
let task = self.urlSession.dataTask(with: urlRequest, completionHandler: [weak self] (data, response, error) in
guard let strongSelf = self else
return
if let errorResponse = error
//strongSelf.result = Result.failure(errorResponse)
strongSelf.onCompletion?(Result.failure(errorResponse))
if let responseFromServer = response as? HTTPURLResponse,
200...299 ~= responseFromServer.statusCode
if let dataResponse = data
//strongSelf.result = Result.success(dataResponse)
strongSelf.onCompletion?(Result.success(dataResponse))//it hits this point
else
strongSelf.onCompletion?(Result.failure(NSError()))
strongSelf.urlSession.invalidateAndCancel()
)
task.resume()
我正在为它编写一个单元测试,但它似乎没有在完成块中,即使它命中了:strongSelf.onCompletion?(Result.success(dataResponse))
到目前为止,单元测试是这样的:
func test_getNetworkConnection()
let promise = expectation(description: "Completion handler invoked")
sut?.getNetworkConnection(urlRequest: URLRequest(url: requestURL), completionHandler: (data) in
print(data) //never prints
promise.fulfill()
)
wait(for: [promise], timeout: 100, enforceOrder: true)//exaggerated timeout but it fails
// XCTAssertTrue(returnedResponse!)
知道可能是什么问题吗?
【问题讨论】:
您是在测试实际连接还是在测试 Mock? 【参考方案1】:你有一些问题。
-
在数据任务的完成块中,您正在调用
strongSelf.onCompletion?...
,但onCompletion
是nil
,所以它什么也不做。
您的getNetworkConnection
函数有一个您从不使用的completionHandler
参数。
您对getNetworkConnection
的调用取决于被调用的completionHandler
。
onCompletion
属性似乎没有意义。
在数据任务中,将对strongSelf.onCompletion?...
的调用替换为对completionHandler
参数的调用。
typealias ResultType = Result<Data>
typealias CompletionType = (ResultType) -> ()
internal func getNetworkConnection(urlRequest: URLRequest, completionHandler: @escaping CompletionType)
let task = self.urlSession.dataTask(with: urlRequest, completionHandler: [weak self] (data, response, error) in
guard let strongSelf = self else
return
if let errorResponse = error
completionHandler(Result.failure(errorResponse))
if let responseFromServer = response as? HTTPURLResponse,
200...299 ~= responseFromServer.statusCode
if let dataResponse = data
completionHandler(Result.success(dataResponse))
else
completionHandler(Result.failure(NSError()))
else
// TODO - need to call completionHandler here too
strongSelf.urlSession.invalidateAndCancel()
)
task.resume()
【讨论】:
做得很好。非常感谢!以上是关于完成处理程序不返回任何内容,即使它看起来像在单步执行时的主要内容,如果未能解决你的问题,请参考以下文章