RxExpect is a testing framework for RxSwift.
Provide inputs then test outputs. This is an example code that tests map()
operator multiplying the values by 2.
func testMultiply() {
RxExpect("it should multiply values by 2") { test in
let value = PublishSubject<Int>()
let result = value.map { $0 * 2 }
// provide inputs
test.input(value, [
next(100, 1),
next(200, 2),
next(300, 3),
completed(400)
])
// test output
test.assert(result)
.equal([
next(2),
next(4),
next(6),
completed(400)
])
}
}
It would be easy to understand if you imagine the marble diagram.
time --100-200-300-400 // virtual timeline
value --1---2---3---| // provide inputs
result --2---4---6---| // test these values
This is more complicated example.
final class ArticleDetailViewModelTests: RxTestCase {
func testLikeButtonSelected() {
RxExpect("like button should become selected when like button tapped") { test in
let viewModel = ArticleDetailViewModel()
// providing an user input: user tapped like button
test.input(viewModel.likeButtonDidTap, [
next(100),
])
// test output: like button become selected
test.assert(viewModel.isLikeButtonSelected)
.filterNext()
.since(100)
.equal([true])
}
RxExpect("like button should become unselected when like button tapped") { test in
let viewModel = ArticleDetailViewModel()
// providing an user input: user tapped like button
test.input(viewModel.likeButtonDidTap, [
next(100),
])
// test output: like button become selected
test.assert(viewModel.isLikeButtonSelected)
.filterNext()
.since(100)
.equal([false])
}
}
}
input(observer, events)
input(variable, events)
assert(source)
filterNext()
since(timeSince)
until(timeUntil)
within(timeRange)
not()
equal(expectedEvents)
isEmpty()
contains()
-
For iOS 8+ projects with CocoaPods:
pod 'RxExpect', '~> 0.5'
-
For iOS 8+ projects with Carthage:
github "devxoul/RxExpect" ~> 0.5
$ git clone https://github.com/devxoul/RxExpect
$ cd RxExpect
$ carthage checkout --no-use-binaries
$ open RxExpect.xcworkspace
RxExpect is under MIT license. See the LICENSE file for more info.