Introduction to RxTest - tasanobu tech blog
I had a presentation (in Japanese) about RxTest at RxSwift Meetup held at Tokyo.
There does not seem to be lots of RxTest related materials on the web so I decided to translate the presentation into English and to write this post.
Notes
This post is based on
- Xcode 8.1 / Swift 3.0
- RxSwift 3.0.0
- RxTest 3.0.0
The code shown in this post is published on my GitHub repository here .
What is RxTest?
- RxTest is a test framework published at RxSwift repository.
- Most(All?) of the unit testing in RxSwift is implemented with RxTest
- RxTest is available for third-party like normal app developers and it’s easy to add it to your test target with Cocoapods by adding the code like below to your podfile.
1 | target 'RxTest-SampleTests' do |
Main classes of RxTest
TestScheduler
- is a scheduler in which virtual time is implemented.
- emits events and executes arbitrary closures based on virtual time.
- has factory methods to instantiate
TestableObserver
andTestObservable
TestableObservable
- is an observable sequence which has events sent to observer at the designated virtual time and records subscriptions(subscribe/unsubscribe) during its lifetime
TestableObserver
- is an observer which records all emitted events together with virtual time when they were received.
Samples
Let’s see how to use the classes introduced above.
map operator
The following is the test code of map operetor in RxSwift (I simplified a little.)
1 | func test_map() { |
ViewModel of Github follower search view
As a more practical example, let’s see the view model for Github follower search view.
ViewModel
The following class is the view model for the view and it is the test target.
1 | class SearchViewModel { |
There are 2 important points from unit testing perspective.
- Pass a
Client
object toSearchModelView
‘s initializer - Call
Client.fetchFollowers()
insideSearchViewModel
Mock Client
The following class is the mock object of Client
which is used for unit testing.
The mock class inherits Client
(in order to simplify the sample).
It has a property response
which is a TestableObservable
used as API response and overrides fetchFollowers()
and returns response
from it.
1 | class MockClient: Client { |
Test code: SearchViewModel.state
Below is the test sample of SearchViewModel.state
.
The value of the property changes in response to searchFollowers()
which causes network request.
The overall flow is almost the same as the previous example of map
operator.
1 | func test_state_when_searchFollowers_succeeded() { |
Wrap up
This post describes the overview of RxTest and the examples of unit testing with RxTest.
You might think it’s hard to get into unit testing of features implemented with RxSwift.
However, it’s doable to write such test code by following the steps below.
- Instantiate TestScheduler
- As TestableObservable, instantiate an event sequence which you want to inspect
- Instantiate TestableObserver which records events to be inspected
- Make TestableObserver subscribe TestableObservable
- Start TestScheduler
- Inspect TestableObserver.events or TestableObservable.subscriptions depending on your test needs.
From:
- Introduction to RxTest - tasanobu tech blog