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()))
}
}
}
}