Posts

Post not yet marked as solved
0 Replies
162 Views
Hi All, I want to learn and write unit test cases using Mock class and stubs for MVVM design implementation. Also I want to test API calls using XCTestCase framweork. I need recommended guidelines or way for writing test cases for following class designs. I am facing problem for how to test code/data from mock class with actual class code. Thanks in Advance for valuable help. Please ignore hardcoded error values. //NetworkManager.swift protocol GetAPIRquestData { var path: String { get set } var method: String { get set } func getAPIData(_ completion: @escaping (Result<Data, Error>) -> Void) -> Void } class NetworkManager: GetAPIRquestData { var path: String var method: String private let session: URLSession init(session: URLSession = URLSession(configuration: .default), path: String, method: String) { self.session = session self.path = path self.method = method } func getAPIData(_ completion: @escaping (Result<Data, Error>) -> Void) -> Void { guard let request = try? buildRequest() else { return } let task = session.dataTask(with: request) { data, response, error in if let data = data { if let response = response as? HTTPURLResponse, response.statusCode == 200 { completion(.success(data)) } else { completion(.failure(NSError(domain: "Invalid data", code: 205, userInfo: nil))) } } else { completion(.failure(NSError(domain: "Data error", code: 400, userInfo: nil))) } } task.resume() } func buildRequest() throws -> URLRequest { // Construct a URL by assigning its parts to a URLComponents value var components = URLComponents() components.scheme = "https" components.host = "api.developer.com" components.path = self.path // This will give us the constructed URL as an optional guard let url = components.url else { throw NSError(domain: "Invalid URL", code: 10, userInfo: nil) } var request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalAndRemoteCacheData, timeoutInterval: 10) request.httpMethod = self.method return request } } //HomeUsersViewModel.swift struct UsersViewModel { let loginUserName: String? let avatarUrl: String? init(userModel: HomeUsersModelElement) { self.loginUserName = userModel.login self.avatarUrl = userModel.avatarURL } } protocol ParsableData { var arrayUsersViewModel: [UsersViewModel] { get set } var output: OutputHomeViewData? { get set } func getParsableData() -> Void } protocol OutputHomeViewData: AnyObject { func didReceivedOutPutData(_ userViewModel: [UsersViewModel]?, error: Error?) -> Void } final class HomeUsersViewModel: ParsableData { weak var output: OutputHomeViewData? var arrayUsersViewModel: [UsersViewModel] = [] private let getApiData: GetAPIRquestData init(getApiData: GetAPIRquestData){ self.getApiData = getApiData } func getParsableData() -> Void { getApiData.getAPIData { result in switch result { case .success(let data): do { let jsonData = try JSONDecoder().decode(HomeUsersModel.self, from: data) let viewModel = self.mapModelDataToViewModelData(userModel: jsonData) self.output?.didReceivedOutPutData(viewModel, error: nil) } catch let error { self.output?.didReceivedOutPutData(nil, error: error) } case .failure(let err): self.output?.didReceivedOutPutData(nil, error: err) } } } //Map API response data to View Model and assign to delegete object. func mapModelDataToViewModelData(userModel: HomeUsersModel) -> [UsersViewModel] { let modelArray = userModel.map { (obj: HomeUsersModelElement) -> UsersViewModel in return UsersViewModel(userModel: obj) } return modelArray } } //HomeUsersViewController.swift class HomeUsersViewController: UIViewController {    private var parsableData: ParsableData = HomeUsersViewModel(getApiData: NetworkManager(session: URLSession(configuration: .default), path: "/users", method: "GET"))   private var userVM: [UsersViewModel] = []   override func viewDidLoad() {     super.viewDidLoad()          parsableData.getParsableData()     parsableData.output = self   } } extension HomeUsersViewController: OutputHomeViewData {       func didReceivedOutPutData(_ userViewModel: [UsersViewModel]?, error: Error?) {     if let userVM = userViewModel {       self.userVM = userVM       print("VM:\(self.userVM)")     } else if let _ = error {             } else {       }   } }
Posted
by VishalP.
Last updated
.