рдореБрд╕реАрдмрдд
рдУрдмреАрдЬреАрд╕реА / рд╕реА ++ рд╕реЗ рд╕реНрд╡рд┐рдлреНрдЯ рдХреА рджреБрдирд┐рдпрд╛ рдореЗрдВ рдХрджрдо рд░рдЦрддреЗ рд╣реБрдП, рдореИрдВ рдЗрдХрд╛рдИ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрддреЗ рд╕рдордп рдПрдХ рд╕рдорд╕реНрдпрд╛ рдореЗрдВ рднрд╛рдЧ рдЧрдпрд╛: рдЬреЙрдХ рдСрдмреНрдЬреЗрдХреНрдЯ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдкрдХрд░рдгреЛрдВ рдХреА рдХрдореАред
рд╡рд┐рдШрдЯрд┐рдд рдХреЛрдб рд▓рд┐рдЦрддреЗ рд╕рдордп, рд╣рдо рдЕрдХреНрд╕рд░ рдЗрдВрдЯрд░рдлреЗрд╕ (рдкреНрд░реЛрдЯреЛрдХреЙрд▓) рдХреЗ рдкреАрдЫреЗ рдХрд╛рд░реНрдпрд╛рдиреНрд╡рдпрди рд╡рд┐рд╡рд░рдг рдЫрд┐рдкрд╛рддреЗ рд╣реИрдВред рдореЛрдХрд╛рдореА рдХреЗ рд╕рд╛рде рдЗрд╕рдХреЗ рдШрдЯрдХ рднрд╛рдЧреЛрдВ рдХреА рдЬрдЧрд╣, рджреВрд╕рд░реЛрдВ рд╕реЗ рдЕрд▓рдЧ рд╕реЗ рдХрд┐рд╕реА рд╡рд╕реНрддреБ рдХреА рдХрд╛рд░реНрдпрдХреНрд╖рдорддрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдирд╛ рднреА рдмрд╣реБрдд рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рд╣реИред
Googling, рдореБрдЭреЗ рдЧрд┐рддреБрдм рдкрд░ рдХрдИ рд╕реНрд╡рд┐рдлреНрдЯ рдореЙрдХрд┐рдВрдЧ рдлреНрд░реЗрдорд╡рд░реНрдХ рдорд┐рд▓реЗред рд▓реЗрдХрд┐рди рдЙрдирдореЗрдВ рд╕реЗ рдХреЛрдИ рднреА рдореБрдЭреЗ рд╕реНрдкрд╖реНрдЯ рдФрд░ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдореЗрдВ рдирд╣реАрдВ рдЖрдпрд╛ (рдПрдХ рдпрд╛ рдХрдИ рдХрд╛рд░рдгреЛрдВ рд╕реЗ):
- рдирд┐рд░реНрднрд░рддрд╛ рдХрд╛ рдПрдХ рдмрд╛рджрд▓ рд╣реИ
- рдХреЛрдИ рд╕рд╣рдЬ рд╡рд╛рдХреНрдпрд╡рд┐рдиреНрдпрд╛рд╕ рдирд╣реАрдВ
- рдмрдбрд╝реА рдорд╛рддреНрд░рд╛ рдореЗрдВ рд╕рд╣рд╛рдпрдХ рдХреЛрдб рдХреА рдХреЛрдб рдкреАрдврд╝реА / рдореИрдиреБрдЕрд▓ рд▓реЗрдЦрди рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ
- XCTest рдХреЗ рд╕рд╛рде рдПрдХреАрдХреГрдд рдирд╣реАрдВ рд╣реИ (рдЧреАрд▓рд╛ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдкрд░реАрдХреНрд╖рдг рдирд╣реАрдВ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ)
- рдХрдИ рд╕реБрд╡рд┐рдзрд╛рдУрдВ рдХреЛ рдПрдХ рдврд╛рдВрдЪреЗ рдХреЗ рдПрдХ рд╕рдореВрд╣ рдореЗрдВ рдбрдВрдк рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ (рдХреНрдпрд╛ рдФрд░ рдХреНрдпреЛрдВ рдХрд╛ рднреНрд░рдо)
- рдкреВрд░реНрд╡рдирд┐рд░реНрдзрд╛рд░рд┐рдд / рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдкреНрд░рдХрд╛рд░реЛрдВ рдХреА рд╕реАрдорд┐рдд рд╕рдВрдЦреНрдпрд╛ рдХреЗ рд╕рд╛рде рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП
рдпрд╣ рд╕реНрдерд┐рддрд┐ рдореЗрд░реЗ рд▓рд┐рдП рдЕрдкреНрд░рд┐рдп рдереА, рдФрд░ рд▓рдЧрднрдЧ рдПрдХ рд╕рд╛рд▓ рддрдХ рдореИрдВрдиреЗ рд╡рд░реНрдХрдЖрд░реНрд╕ рдФрд░ рд╕реНрд╡-рдирд┐рд░реНрдорд┐рдд рдореЛрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ред
рд╕реНрд╡-рд▓рд┐рдЦрд┐рдд рдирдХрд▓реА рд╡рд╕реНрддреБрдПрдВ рд╕рд░рд▓ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡реЗ
- рд╣рд░ рдмрд╛рд░ рдЕрд▓рдЧ (рдкрд╣рд┐рдпрд╛ рдХреЛ рд╕реБрджреГрдврд╝ рдХрд░реЗрдВ)
- рдпрд╛ рд╣рд░ рдмрд╛рд░ (рдХреЙрдкреА-рдкреЗрд╕реНрдЯ)
- рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕реНрдкрд╖реНрдЯ рдирд╣реАрдВ рд╣реИ
рдлреЗрд╕рд▓рд╛
C ++ gTest / gMock ( Google).
Mock- . , ┬л┬╗ ( ) .
gMock, sMock (Swift Mock) gMock.
https://github.com/Alkenso/sMock
sMock:
- mock /
- expectations
- - mock-
- XCTest.framework
- zero-dependency
- pure Swift
()
sMock
- Mock , ( )
- Mock methodCall. "" .
Mocking synchronous method
:
import XCTest
import sMock
protocol HTTPClient {
func sendRequestSync(_ request: String) -> String
}
class MockHTTPClient: HTTPClient {
let sendRequestSyncCall = MockMethod<String, String>()
func sendRequestSync(_ request: String) -> String {
sendRequestSyncCall.call(request) ?? ""
}
}
struct Client {
let httpClient: HTTPClient
func retrieveRecordsSync() -> [String] {
let response = httpClient.sendRequestSync("{ action: 'retrieve_records' }")
return response.split(separator: ";").map(String.init)
}
}
class ExampleTests: XCTestCase {
func test_Example() {
let mock = MockHTTPClient()
let client = Client(httpClient: mock)
mock.sendRequestSyncCall
.expect("Request sent.")
.match("{ action: 'retrieve_records' }")
.willOnce(
.return("r1;r2;r3"))
let records = client.retrieveRecordsSync()
XCTAssertEqual(records, ["r1", "r2", "r3"])
}
}
Mocking synchronous method + mocking asynchonous callback
Mock callback'a, .
protocol HTTPClient {
func sendRequestSync(_ request: String) -> String
}
class MockHTTPClient: HTTPClient {
let sendRequestSyncCall = MockMethod<String, String>()
func sendRequestSync(_ request: String) -> String {
sendRequestSyncCall.call(request) ?? ""
}
}
struct Client {
let httpClient: HTTPClient
func retrieveRecordsAsync(completion: @escaping ([String]) -> Void) {
let response = httpClient.sendRequestSync("{ action: 'retrieve_records' }")
completion(response.split(separator: ";").map(String.init))
}
}
class ExampleTests: XCTestCase {
func test_Example() {
let mock = MockHTTPClient()
let client = Client(httpClient: mock)
mock.sendRequestSyncCall
.expect("Request sent.")
.match("{ action: 'retrieve_records' }")
.willOnce(
.return("r1;r2;r3"))
let completionCall = MockClosure<[String], Void>()
completionCall
.expect("Records retrieved.")
.match(["r1", "r2", "r3"])
.willOnce()
client.retrieveRecordsAsync(completion: completionCall.asClosure())
sMock.waitForExpectations()
}
}
Matchers, Actions, Argument capture
sMock (. ):
- Matchers тАФ , .match: .any ( )
- Actions: expectation match'e .return, .
- : expectation .
- : , unexpectedCall
.
.
: , . .
, Swift .
, sMock . .
"testing with Swift"!
Try sMock on github (with SwiftPackageManager)