gpt4 book ai didi

ios - Swift 中可测试的异步设计模式

转载 作者:搜寻专家 更新时间:2023-10-31 19:38:25 24 4
gpt4 key购买 nike

我正在学习 Swift 中的测试驱动开发。当我意识到我经常用于异步请求的委托(delegate)模式很难测试时,我遇到了困难。我了解到,如果某些东西难以测试,那么实现背后的设计模式可能会更好。这让我感到困惑,因为我认为我使用的委托(delegate)模式很常见,我想知道其他人是如何处理这个问题的。

模式:

我编写了一个服务,它在采用委托(delegate)实例的静态函数中执行异步请求。委托(delegate)实例符合需要实现成功和失败方法的协议(protocol)。我设计了一个点击 Google.com 的示例。请忽略此示例中的类型安全问题。我正在运行的用于访问端点并解析 JSON 的实际代码更安全。我只是想提出一小段代码来描述导致测试困难的问题:

protocol GoogleServiceDelegate {
func gotGoogle(str: String);
func gotError(str: String);
}

struct GoogleService {
static func getGoogle(delegate: GoogleServiceDelegate) {
let url: NSURL! = NSURL(string: "http://google.com")
NSURLSession.sharedSession().dataTaskWithURL(url) { data, response, error in
if let data = data {
let str: NSString! = NSString(data: data, encoding: NSUTF8StringEncoding)
delegate.gotGoogle(str as String)
} else {
delegate.gotError("\(error)")
}
}
}
}

下面是说明问题的测试:

class AsyncTestingTests: XCTestCase {

func testExample() {
let responseExpectation = expectationWithDescription("Got google response!")

struct GoogleDelegate: GoogleServiceDelegate {
func gotGoogle(str: String) {
// expectations about response
responseExpectation.fulfill()
}

func gotError(str: String) {
// expectations about error
responseExpectation.fulfill()
}
}

let myGoogleServiceDelegate = GoogleDelegate()
GoogleService.getGoogle(myGoogleServiceDelegate)

waitForExpectationsWithTimeout(5) { _ in
print("Never got a response from Google :(")
}
}
}

问题出现在两个 .fulfill() 行。我从 Xcode 收到以下错误:

Struct declaration cannot close over value 'responseExpectation' defined in outer scope

我理解错误,但不确定要调整什么...是否有我可以在测试中使用的解决方法,或者是否有比我正在尝试的更好(易于测试)的异步回调模式?如果您知道更好的可测试解决方案,您介意花时间写下示例吗?

最佳答案

是的,您不能关闭在结构外部定义的变量,要解决这个问题,我们需要使用闭包/函数并将其传递给结构。 struct 中的方法可以在收到响应时调用它。

    func testExample() {
let responseExpectation = expectationWithDescription("Got google response!")

//Let a function capture the fulfilling of the expectation
func fullFillExpectation(){

responseExpectation.fullFill()
}

struct GoogleDelegate: GoogleServiceDelegate {

var fullFiller : (()->Void)!
func gotGoogle(str: String) {
// expectations about response via invoke the closure
fullFiller()
}

func gotError(str: String) {
// expectations about error - invoke the closure
fullFiller()
}
}

//Create the delegate with full filler function.
let myGoogleServiceDelegate = GoogleDelegate(fullFiller: fullFillExpectation)
GoogleService.getGoogle(myGoogleServiceDelegate)

waitForExpectationsWithTimeout(5) { _ in
print("Never got a response from Google :(")
}
}
}

PS:我无法测试这个,请测试并告诉我。

关于ios - Swift 中可测试的异步设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34781878/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com