Очевидный ответ - ввести dataTask вместо использования синглтона внутри вашей функции. Примерно так:
func getRecipes(query: String, _ needsMoreData: Bool, dataTask: @escaping (URL, @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask) -> Observable<[Recipes]> {
guard let url = URL(string: "https://api.spoonacular.com/recipes/search?\(query)&apiKey=myApiKey") else {
return Observable.just([])
}
return Observable.create { observer in
let task = dataTask(url) { (data, response, error) in
// and so on...
Вы бы назвали это в основном коде так:
getRecipes(query: "", false, dataTask: URLSession.shared.dataTask(with:completionHandler:))
В вашем тесте вам понадобится что-то вроде этого:
func fakeDataTask(_ url: URL, _ completionHandler: @escaping (Data?, URLResponse?, Error?) -> Void) -> URLSessionDataTask {
XCTAssertEqual(url, expectedURL)
completionHandler(testData, nil, nil)
return URLSessionDataTask()
}
let result = getRecipes(query: "", false, dataTask: fakeDataTask)
Знаете ли вы, что для URLSession уже созданы реактивные расширения? Больше всего мне нравится: URLSession.shared.rx.data(request:)
, который возвращает Observable, который выдаст ошибку, если возникнут проблемы с получением данных. Я предлагаю вам использовать его.