Я изучаю Test Driven Development в Swift. Я ударил стену, когда понял, что шаблон делегата, который я регулярно использую для асинхронных запросов, трудно проверить. Я узнал, что если что-то трудно проверить, дизайн схемы реализации, возможно, будет лучше. Это меня смущает, потому что я считаю, что шаблон делегата, который я использую, является общим, и мне интересно, как другие справились с этой проблемой.Тестируемый шаблон асинхронного проектирования в Swift
Узор:
Я написал службу, которая выполняет асинхронный запрос в статической функции, которая принимает экземпляр делегата. Экземпляр делегата соответствует протоколу, который требует реализации метода успеха и отказа. Я придумал пример, который попадает на сайт 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 декларация не может закрыть над значением «responseExpectation» определено в внешней области
Я понимаю ошибку, но не уверен, что нужно подстраивать ... Есть обходной путь для этого, который я могу использовать в тесте, или есть лучший (легко проверяемый) шаблон для асинхронных обратных вызовов, чем то, что я пытаюсь сделать? Если вы знаете о более надежном тестируемом решении, не могли бы вы потратить время, чтобы записать пример?
Это сработало! Спасибо! – pachun
Полезно знать: - – Shripada