Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- Code
- github
- appstore
- darkmode
- 개발자
- Realm
- 웹뷰
- 이미지
- Firebase
- Session
- Archive
- JPA
- Git
- iOS16
- mac
- Notification
- IOS
- geofencing
- Apple
- view
- FLUTTER
- error
- rxswift
- MacOS
- Swift
- SwiftUI
- window
- 한글
- UIButton
- Xcode
Archives
- Today
- Total
EEYatHo 앱 깎는 이야기
Swift ) ReactorKit (2) 테스트 - EEYatHo iOS 본문
반응형
ReactorKit 에서 테스트 대상
3가지로 나눠서 확인할 수 있다
- View -> Reactor
- 유저의 인터렉션이 일어났을 때, Reactor 에게 기대되는 Action 을 넘기는지
- Reactor -> View
- Reactor 에서 도달한 State 값에 따라 View 의 property 들이 기대한대로 설정되는지
- Reactor Processing ( Action - mutation -> State )
- 특정 State에서 특정 Action이 들어왔을 때 State 가 기대한대로 변경되는지
Stub
ReactorKit 은 용이한 Test 를 위해, Reactor 에 Stub 이라는 기능을 제공한다.
아래처럼 Reactor 에서 Stub 기능을 사용할 것인지 설정할 수 있다.
let reactor = MyReactor()
reactor.isStubEnabled = true
Stub 이 활성화된 Reactor 는 mutate(), reduce() 가 실행되지 않는다.
( = View -> Reactor, Reactor -> View 케이스에서만 사용해야 한다. )
Stub 이 활성화된 Reactor 는 아래의 특정 프로퍼티들을 사용할 수 있다.
Stub 에서 제공하는 Property 들
var state: StateRelay<Reactor.State> { get } // State를 간단하게 설정할 수 있음
var action: ActionSubject<Reactor.Action> { get }
var actions: [Reactor.Action] { get } // 어떤 Action들이 들어왔는지 기록
Stub 사용법 예시
// View --Action-> Reactor
func testAction_refresh() {
// 1. prepare a stub reactor
let reactor = MyReactor()
reactor.isStubEnabled = true
// 2. prepare a view with a stub reactor
let view = MyView()
view.reactor = reactor
// 3. send an user interaction programmatically
view.refreshControl.sendActions(for: .valueChanged)
// 4. assert actions
XCTAssertEqual(reactor.stub.actions.last, .refresh)
}
// Reactor --State-> View
func testState_isLoading() {
// 1. prepare a stub reactor
let reactor = MyReactor()
reactor.isStubEnabled = true
// 2. prepare a view with a stub reactor
let view = MyView()
view.reactor = reactor
// 3. set a stub state
reactor.stub.state.value = MyReactor.State(isLoading: true)
// 4. assert view properties
XCTAssertEqual(view.activityIndicator.isAnimating, true)
}
// Reactor Proccesing
func testIsBookmarked() {
let reactor = MyReactor()
reactor.action.onNext(.toggleBookmarked)
XCTAssertEqual(reactor.currentState.isBookmarked, true)
reactor.action.onNext(.toggleBookmarked)
XCTAssertEqual(reactor.currentState.isBookmarked, false)
}
단일 작업에 대해 State 가 여러번 변경되는 경우 테스트 예제 with RxTest
func testIsLoading() {
// given
let scheduler = TestScheduler(initialClock: 0)
let reactor = MyReactor()
let disposeBag = DisposeBag()
// when
scheduler
.createHotObservable([
.next(100, .refresh) // send .refresh at 100 scheduler time
])
.subscribe(reactor.action)
.disposed(by: disposeBag)
// then
let response = scheduler.start(created: 0, subscribed: 0, disposed: 1000) {
reactor.state.map(\.isLoading)
}
XCTAssertEqual(response.events.map(\.value.element), [
false, // initial state
true, // just after .refresh
false // after refreshing
])
}
'iOS, Swift > ArchitecturePattern' 카테고리의 다른 글
Swift ) Clean Architecture - EEYatHo iOS (0) | 2023.07.21 |
---|---|
Swift ) ReactorKit (1) 개념, 사용법 - EEYatHo iOS (0) | 2022.12.01 |
Swift ) RIBs - EEYatHo iOS (0) | 2021.07.05 |
Swift ) VIPER - EEYatHo iOS (0) | 2021.07.05 |
Swift ) MVVM 탄생과정, 특징 - EEYatHo iOS (0) | 2021.07.05 |
Comments