Skip to content

Instantly share code, notes, and snippets.

@vinhnx
Created September 18, 2019 07:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vinhnx/a83e8dbb1312e48aa3b2bcc7cdb7c276 to your computer and use it in GitHub Desktop.
Save vinhnx/a83e8dbb1312e48aa3b2bcc7cdb7c276 to your computer and use it in GitHub Desktop.
Mocking in Swift
// mocking in swift
// reference: https://www.vadimbulavin.com/real-world-unit-testing-in-swift/
struct User {}
class AuthService {
var client: HTTPClient
// init
init(_ client: HTTPClient) {
self.client = client
}
func login(with username: String, password: String, completion: ((Result<User, Error>) -> Void)? = nil) {
let request = URLRequest.login(username: username, password: password)
// don't do this in tets since tests must be
// URLSession.shared.dataTask(with: request) { _, _, _ in
// // ...
// }.resume()
// use mock instead
self.client.execute(request: request) { _ in
// ...
}
}
}
struct URLConfiguration {
static let baseURL = "https://foo.com"
}
extension URLQueryItem {
static func queries(_ pairs: [String: String]) -> [URLQueryItem] {
return pairs.map { item in
URLQueryItem(name: item.key, value: item.value)
}
}
}
extension URLRequest {
static func login(username: String, password: String) -> URLRequest {
let params = ["username": username,
"password": password]
var urlComponents = URLComponents(string: URLConfiguration.baseURL)
urlComponents?.queryItems = URLQueryItem.queries(params)
let url = urlComponents?.url
return URLRequest(url: url!) // don't do this in production
}
}
protocol HTTPClient {
func execute(request: URLRequest, completion: (Result<Data, Error>) -> Void)
}
// create a HTTPClient mock instance
class HTTPClientMock: HTTPClient {
var request: URLRequest?
var isRequestCalled = false
func execute(request: URLRequest, completion: (Result<Data, Error>) -> Void) {
defer { isRequestCalled = true } // just mark request call as true and do nothing
self.request = request
}
}
import XCTest
// in our test we want to verify that AuthService indeed calls execute
class AuthServiceTests: XCTestCase {
func testLogin() {
// arrange
let client = HTTPClientMock()
let sut = AuthService(client)
// act
sut.login(with: "a", password: "b")
// assert
XCTAssertTrue(client.isRequestCalled)
XCTAssertEqual(client.request?.url,
URLRequest.login(username: "a", password: "b").url)
}
}
@Connor98web
Copy link

This code will be useful to me :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment