Home > OS >  Returning Conditional Responses from MockedWebService in Swift
Returning Conditional Responses from MockedWebService in Swift

Time:10-12

I am implementing UI Testing and need to mock a service so I don't call the service again and again and remove the dependency on the network call. So, I created a Mock called MockWebservice. It is implemented below:

class MockedWebservice: NetworkService {
    
    func login(username: String, password: String, completion: @escaping (Result<LoginResponse?, NetworkError>) -> Void) {
        
            completion(.success(LoginResponse(success: true)))
       
    }
}

It works but as you can see it always returns success: true. How can I make this MockedWebservice return a different response. The MockWebservice is injected into the main app using the launchEnvironment for unit test. Here is the code in the actual SwiftUI App which creates a real web service or a mocked version.

class NetworkServiceFactory {
    
    static func create() -> NetworkService {
        
        let environment = ProcessInfo.processInfo.environment["ENV"]
        
        if let environment = environment {
            if environment == "TEST" {
                return MockedWebservice()
            } else {
                return Webservice()
            }
        } else {
            return Webservice()
        }
        
    }
    
}

CodePudding user response:

Add some logic to your mocked service so that it responds differently depending on the username/password it receives

Something like:

class MockedWebservice: NetworkService {
    
    func login(username: String, password: String, completion: @escaping (Result<LoginResponse?, NetworkError>) -> Void) {
        
        if username == "success" {
            completion(.success(LoginResponse(success: true)))
        } else {
            completion(.failure(SomeNetworkError()))
        }
    }
}

You can test for additional username values to simulate different responses.

I would probably make the mocked method a bit more realistic. Use an asyncAfter on a utility dispatch queue to simulate network latency and the fact that your completion handler probably wont be called on the main queue.

class MockedWebservice: NetworkService {
    
    func login(username: String, password: String, completion: @escaping (Result<LoginResponse?, NetworkError>) -> Void) {
        DispatchQueue.global(qos: .utility).asyncAfter(.now() 0.5) {
            if username == "success" {
                completion(.success(LoginResponse(success: true)))
            } else {
                completion(.failure(SomeNetworkError()))
            }
        }
    }
}
  • Related