Weitere ähnliche Inhalte Ähnlich wie トークンリフレッシュ処理を含むAPIClientのテスト #hakata_test_night (20) Mehr von Kenji Tanaka (20) Kürzlich hochgeladen (20) トークンリフレッシュ処理を含むAPIClientのテスト #hakata_test_night16. • Interactor - APIClient SessionManager
• Refresh Request
• Refresh Request
• APIKit→Alamofire
• APIKit Refresh/Retry
• Request-Completion
Alamofire
23. - 1
•
• [200]
• [400]
• [401]
• [401, 200(refresh), 200(retry)]
• [401, 200(refresh), 400(retry)]
• [401, 200(refresh), 401(retry)]
Refresh/Retry
25. - 2
•
• [200(a), 200(b)] / [400(a), 400(b)] (ab )
• [401(a), 200(a, refresh), 200(a, retry), 200(b)] (ab )
• [401(a), 200(a, refresh), 400(a, retry), 200(b)] (ab )
• [401(a), 400(a, refresh), 401(b)] (ab )
• [401(a), 401(a, refresh), 401(b)] (ab )
27. - 2
•
• [200(a), 200(b)] / [400(a), 400(b)] (ab )
• [400(a), 401(b)] / [200(a) / 400(b)] (ab , 1 )
• [401(a), 401(b), 200(a, refresh), 200(a, retry), 200(b, retry)] (b Refresh )
• [401(a), 200(a, refresh), 401(b), 200(a, retry), 200(b, retry)] (b Refresh )
• etc…
34. Stub
var responses = [authError, successWithAccessToken, success]
stub(condition: isHost("example.com")) { request in
return responses.removeFirst()
}
// ......
// ...
OHHTTPStubs.removeAllStubs()
responses test function …
36. Stub
struct HTTPStub {
static func activate(condition: @escaping OHHTTPStubsTestBlock,
responses: [OHHTTPStubsResponse]) {
var responsesArray = responses
stub(condition: condition) { request in
let response = responsesArray.removeFirst()
return response
}
}
static func deactivate() {
OHHTTPStubs.removeAllStubs()
}
}
38. XCTContext
XCTContext.runActivity(named: case1) { [weak self] _ in
HTTPStub.activate(responses: [authError, successWithAccesstoken, success])
expectation.expectedFulfillmentCount = 1
sessionManager.requestData(TestRequest())
.subscribe(onSuccess: { data, _ in
let success = try? JSONDecoder().decodeSuccess(from: data)
XCTAssertEqual(success, OHHTTPStubsResponse.Success(data: "Success"))
expectation.fulfill()
}, onError: { error in
XCTFail(error.localizedDescription)
expectation.fulfill()
}).disposed(by: disposeBag)
self?.waitForExpectations(timeout: 1.0)
clean()
}
39. XCTContext
XCTContext.runActivity(named: case1) { [weak self] _ in
HTTPStub.activate(responses: [authError, successWithAccesstoken, success])
expectation.expectedFulfillmentCount = 1
sessionManager.requestData(TestRequest())
.subscribe(onSuccess: { data, _ in
let success = try? JSONDecoder().decodeSuccess(from: data)
XCTAssertEqual(success, OHHTTPStubsResponse.Success(data: "Success"))
expectation.fulfill()
}, onError: { error in
XCTFail(error.localizedDescription)
expectation.fulfill()
}).disposed(by: disposeBag)
self?.waitForExpectations(timeout: 1.0)
clean()
}
👃
40. XCTContext
XCTContext.runActivity(named: case1) { [weak self] _ in
HTTPStub.activate(responses: [authError, successWithAccesstoken, success])
expectation.expectedFulfillmentCount = 1
sessionManager.requestData(TestRequest())
.subscribe(onSuccess: { data, _ in
let success = try? JSONDecoder().decodeSuccess(from: data)
XCTAssertEqual(success, OHHTTPStubsResponse.Success(data: "Success"))
expectation.fulfill()
}, onError: { error in
XCTFail(error.localizedDescription)
expectation.fulfill()
}).disposed(by: disposeBag)
self?.waitForExpectations(timeout: 1.0)
clean()
}
Stub 👀
41. XCTContext
XCTContext.runActivity(named: case1) { [weak self] _ in
HTTPStub.activate(responses: [authError, successWithAccesstoken, success])
expectation.expectedFulfillmentCount = 1
sessionManager.requestData(TestRequest())
.subscribe(onSuccess: { data, _ in
let success = try? JSONDecoder().decodeSuccess(from: data)
XCTAssertEqual(success, OHHTTPStubsResponse.Success(data: "Success"))
expectation.fulfill()
}, onError: { error in
XCTFail(error.localizedDescription)
expectation.fulfill()
}).disposed(by: disposeBag)
self?.waitForExpectations(timeout: 1.0)
clean()
}
expectation 👀
42. XCTContext
XCTContext.runActivity(named: case1) { [weak self] _ in
HTTPStub.activate(responses: [authError, successWithAccesstoken, success])
expectation.expectedFulfillmentCount = 1
sessionManager.requestData(TestRequest())
.subscribe(onSuccess: { data, _ in
let success = try? JSONDecoder().decodeSuccess(from: data)
XCTAssertEqual(success, OHHTTPStubsResponse.Success(data: "Success"))
expectation.fulfill()
}, onError: { error in
XCTFail(error.localizedDescription)
expectation.fulfill()
}).disposed(by: disposeBag)
self?.waitForExpectations(timeout: 1.0)
clean()
} 👀
43. XCTContext
XCTContext.runActivity(named: case1) { [weak self] _ in
HTTPStub.activate(responses: [authError, successWithAccesstoken, success])
expectation.expectedFulfillmentCount = 1
sessionManager.requestData(TestRequest())
.subscribe(onSuccess: { data, _ in
let success = try? JSONDecoder().decodeSuccess(from: data)
XCTAssertEqual(success, OHHTTPStubsResponse.Success(data: “Success"))
expectation.fulfill()
}, onError: { error in
XCTFail(error.localizedDescription)
expectation.fulfill()
}).disposed(by: disposeBag)
self?.waitForExpectations(timeout: 1.0)
clean()
}
👀
44. XCTContext
extension XCTContext {
static func runWaitActivity(testCase: XCTestCase,
name name: String,
timeout: TimeInterval = 1.0,
prepare: (() -> Void)? = nil,
then: (XCTestExpectation) -> Void,
clean: (() -> Void)? = nil) {
runActivity(named: named) { _ in
let expectation = name
prepare?()
then(expectation)
testCase.waitForExpectations(timeout: timeout, handler: nil)
clean?()
}
}
}
45. XCTContext
XCTContext
.runWaitActivity(testCase: self, named: case1, prepare: {
HTTPStub.activate(responses: [authError, successWithAccesstoken, success])
}, then: { expectation in
expectation.expectedFulfillmentCount = 1
sessionManager.requestData(TestRequest())
.subscribe(onSuccess: { data, _ in
let success = try? JSONDecoder().decodeSuccess(from: data)
XCTAssertEqual(success, OHHTTPStubsResponse.Success(data: "Success"))
expectation.fulfill()
}, onError: { error in
XCTFail(error.localizedDescription)
expectation.fulfill()
})
.disposed(by: disposeBag)
}, clean: clean)
😄