为使用URLSession和RxSwift的函数编写单元测试

问题描述 投票:1回答:1

我有一个创建并返回Observable的函数,该函数使用URLSession下载和解码数据。我想为此功能编写单元测试,但不知道如何解决。

功能:

func getRecipes(query: String, _ needsMoreData: Bool) -> 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 = URLSession.shared.dataTask(with: url) { (data, response, error) in

                guard let data = data else {
                    return
                }

                do {
                    if self.recipes == nil {
                        self.recipes = try self.decoder.decode(Recipes.self, from: data)
                        self.dataList = self.recipes.results
                        self.baseUrl = self.recipes.baseUrl
                    } else {
                        if needsMoreData {
                            self.recipes = try self.decoder.decode(Recipes.self, from: data)
                            self.dataList.append(contentsOf: self.recipes.results.suffix(50))
                        } else {
                            self.dataList = try self.decoder.decode(Recipes.self, from: data).results
                        }
                    }
                    observer.onCompleted()
                } catch let error {
                    observer.onError(error)
                }
            }
            task.resume()

            return Disposables.create {
                task.cancel()
            }
        }
        .trackActivity(activityIndicator)
    }
swift unit-testing rx-swift urlsession
1个回答
0
投票

显而易见的答案是注入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...

您知道URLSession已经为它创建了Reactive扩展吗?我最喜欢的是:URLSession.shared.rx.data(request:)返回一个Observable,如果获取数据有任何问题,它将发出一个错误。我建议您使用它。

© www.soinside.com 2019 - 2024. All rights reserved.