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
- collectionview
- HIG
- MVVM
- swift documentation
- RxCocoa
- combine
- Clean Code
- tableView
- rxswift
- Xcode
- map
- 리펙토링
- uiscrollview
- 애니메이션
- UICollectionView
- Human interface guide
- clean architecture
- 스위프트
- ios
- SWIFT
- Protocol
- UITextView
- Refactoring
- 클린 코드
- uitableview
- swiftUI
- Observable
- 리팩토링
- ribs
- 리펙터링
Archives
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[UnitTest] RxSwift, MVVM 구조의 테스트 코드 작성 하기 (RxTest, RxNimble) 본문
Unit Test와 UI Test
[UnitTest] RxSwift, MVVM 구조의 테스트 코드 작성 하기 (RxTest, RxNimble)
jake-kim 2021. 2. 12. 09:32* 사용되는 라이브러리
- RxSwift
- RxCocoa
- RxTest (RxSwift의 스트림들을 테스트 할 수 있는, 가상 시간을 함께 이벤트를 발생시킬 수 있는 프레임워크)
- RxNimble (expect라는 함수로 명료하게 테스트를 할 수 있게 해주는 프레임워크)
1. 간단한 RxSwift, MVVM구조 설계
RxSwift구조 코드 참고: ios-development.tistory.com/173
2. Unit 테스트 코드 작성
1) Nimble프레임워크에서 사용 할 events함수 정의
import Foundation
import RxSwift
import RxTest
import Nimble
import RxNimble
// Tests그룹 하위에, ExpectationExtensions.swift에 정의
public extension Expectation where T: ObservableConvertibleType {
internal func transform<U>(_ closure: @escaping (T?) throws -> U?) -> Expectation<U> {
let exp = expression.cast(closure)
return Expectation<U>(expression: exp)
}
func events(scheduler: TestScheduler,
disposeBag: DisposeBag,
startAt initialTime: Int = 0) -> Expectation<[Recorded<Event<T.Element>>]> {
return transform { source in
let results = scheduler.createObserver(T.Element.self)
scheduler.scheduleAt(initialTime) {
source?.asObservable().subscribe(results).disposed(by: disposeBag)
}
scheduler.start()
return results.events
}
}
}
2) Void타입의 Expectation을 비교하기 위해서 함수 정의
import RxSwift
import RxTest
import Nimble
import RxNimble
// Tests그룹 하위에 Operators.swift로 추가
public func equal<Void>(_ expectedValue: Void?) -> Predicate<Void> {
return Predicate.define("equal <\(stringify(expectedValue))>") { actualExpression, msg in
let actualValue = try actualExpression.evaluate()
switch (expectedValue, actualValue) {
case (nil, _?):
return PredicateResult(status: .fail, message: msg.appendedBeNilHint())
case (nil, nil), (_, nil):
return PredicateResult(status: .fail, message: msg)
default:
var isEqual = false
if String(describing: expectedValue).count != 0, String(describing: expectedValue) == String(describing: actualValue) {
isEqual = true
}
return PredicateResult(bool: isEqual, message: msg)
}
}
}
3) 테스트 코드 작성
import XCTest
import RxSwift
import RxCocoa
import RxNimble
import Nimble
import RxTest
@testable import Test
class MyTests: XCTestCase {
var bag: DisposeBag!
var scheduler: TestScheduler!
var viewModel = ToggleVM()
lazy var output = viewModel.transform(input: .init(didTapBtnToggle: didTapBtnToggle.asObservable()))
var didTapBtnToggle: PublishSubject<Void>!
// Given
override func setUp() {
bag = DisposeBag()
scheduler = TestScheduler(initialClock: 0)
viewModel = ToggleVM()
didTapBtnToggle = PublishSubject<Void>()
}
func testAddCount() throws {
// When
scheduler.createColdObservable([
.next(1, ()),
.next(10, ()),
.next(30, ()),
]).bind(to: didTapBtnToggle).disposed(by: bag)
// Then
expect(self.output.toggleCount).events(scheduler: scheduler, disposeBag: bag).to(equal([
.next(0, 0),
.next(1, 1),
.next(10, 2),
.next(30, 3),
]))
}
}
* 전체 코드는 여기에 업로드
'Unit Test와 UI Test' 카테고리의 다른 글
[iOS - swift] Nimble, Quick 프레임워크 (Unit test) (0) | 2021.02.12 |
---|---|
[iOS - swift] BDD (Behavior Driven Development) (given, when ,then) (0) | 2021.02.12 |
[iOS - swift] TDD (Test Driven Development) (2) | 2021.02.12 |
[iOS - swift] Unit test 개념, @testable (0) | 2021.02.11 |
Comments