I want to write unit tests for my DataService. I read that you don't actually want to make network requests in the tests, and instead, you should make a MockDataService. However, what should the body of the fetchBusinesses
method look like in the MockDataService? I need to account for cases of invalidURL, fail to decode etc...
protocol DataServiceProtocol {
func fetchBusinesses(location: CLLocationCoordinate2D) async throws -> [Business]
}
final class DataService: DataServiceProtocol {
func fetchBusinesses(location: CLLocationCoordinate2D) async throws -> [Business] {
let url = try createURL(latitude: location.latitude, longitude: location.longitude)
let request = setupURLRequest(url: url)
let (data, response) = try await URLSession.shared.data(for: request)
guard let response = response as? HTTPURLResponse, response.statusCode == 200 else {
let statusCode = (response as! HTTPURLResponse).statusCode
throw DataServiceError.invalidStatusCode(statusCode: statusCode)
}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let decodedAPIResponse = try decoder.decode(SearchResponse.self, from: data)
return decodedAPIResponse.businesses
}
private func createURL(latitude: Double, longitude: Double) throws -> URL {
let endpoint = "https://api.yelp.com/v3/businesses/search?latitude=\(latitude)&longitude=\(longitude)&sort_by=distance&term=boba"
guard let url = URL(string: endpoint) else {
throw DataServiceError.invalidURL
}
return url
}
private func setupURLRequest(url: URL) -> URLRequest {
let apiKey = "<API Key>"
var request = URLRequest(url: url)
request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
return request
}
}