Одной из наиболее распространенных задач в разработке приложений для iOS является написание сетевого кода. Существует высокая вероятность того, что ваша команда также может разработать собственный бэкэнд-API и не всегда готова к тому, чтобы вы могли проводить интеграционные тесты, когда вам это нужно.
Чтобы создать полнофункциональное демонстрационное приложение, вам нужно смоделировать ответ вашего сервера. Для вас как разработчика iOS есть несколько обходных решений:
- Используйте сторонний сервис, например Postman.
- написать свой собственный фиктивный
localhost
сервер
К счастью, вы можете имитировать ответ сервера прямо в коде Swift/Objective-C, используя URLProtocol
, предоставленный Apple.
Ваш первый протокол MockURL
Прежде всего, давайте создадим ваш класс MockURLProtocol
, унаследовав open class URLProtocol
:
requestHandler
— это место, куда мы позже передадим наш пользовательский ответ сервера.
Нам нужно override
4 функции, рекомендованные Apple:
canInit(with request: URLRequest) -> Bool
canonicalRequest(for request: URLRequest) -> URLRequest
stopLoading()
startLoading()
Интеграция
Затем, вместо использования URLSession.shared
, инициализируйте URLSession
вашим пользовательским URLSessionConfiguration
:
let configuration = URLSessionConfiguration.ephemeral configuration.protocolClasses = [MockURLProtocol.self] let urlSession = URLSession(configuration: configuration) urlSession.dataTask(with: urlRequest) { data, response, error in // ... handle your response }.resume()
Однако я предлагаю добавить флаг Swift, чтобы легко вернуться к исходному коду:
Наконец, передав код ответа примера сервера, предоставленный вашей командой бэкэнда, в requestHandler
:
Настройте свой ответ
Есть 2 основных способа настроить свой ответ:
- Обработка
request
такой информации, как:
MockURLProtocol.requestHandler = {request in // checking URL Path ... if !request.url!.absoluteString.contains("/employeeInfo") { // return 404 HTTPURLResponse } // checking headers ... guard let v = request.allHTTPHeaderFields?["Authorization"] else { return // or throw an error }
2. Наследовать MockURLProtocol
, что очень полезно, если вы создаете разные class
для разных запросов:
Например, если у вас есть класс EmployeeInfoRequest
, вам просто нужно переопределить функцию startLoading
, чтобы передать ваш фиктивный ответ. Затем передайте новый класс EmployeeInfoRequest.iMockURLProtocol
-[URLSessionConfiguration protocolClasses]
Вы можете применить полиморфизм, используя протокол:
Дополнительные преимущества
Помимо поддержки разработчика iOS в создании функционального приложения без готового бэкенда, имитация URLProtocol
на самом деле очень хороша для написания модульных тестов. Передача фиктивного ответа таким образом может помочь вам проверить:
- соответствует ли ваша модель ответу вашего сервера JSON
- Ваш код
URLSession
уже вызываетresume()
?
Чтобы узнать больше о соответствующем тестировании, посетите доклад Apple на WWDC18: Советы и рекомендации по тестированию.