Developing with Kotlin and testing with Spek
TL;DR Tests are specifications. Spek can make them more readable.
This post will showcase the use of Kotlin and Spek with Mockito and RxJava in Android Studio.
For the reasons what are they good for you can check out:
- Android Development with Kotlin by Jake Wharton
- Spek: A BDD testing framework for Kotlin by Laura Kogler
- Testing made sweet with a Mockito by Jeroen Mols
- Learning RxJava by Kaushik Gopal
Setting things up
Dependencies and plugins.
Kotlin
To use Kotlin in Android Studio we need a Kotlin plugin. To install it, go to File | Settings | Plugins | Install JetBrains plugin… and then search for Kotlin. Install and restart the IDE.
Now we can get rid of some Java code using Convert Java File to Kotlin File. To find and invoke this action you can use Find Action.
The only thing left is to Configure kotlin in project. IDE should ask you to do that as soon as it detects a Kotlin file. Invoking this action will automatically modify your build.gradle files to include Kotlin dependencies.
Spek
To use Spek in Android Studio we need to add these dependencies:
testCompile 'org.jetbrains.spek:spek-api:1.1.0-beta3'
testCompile 'org.jetbrains.spek:spek-junit-platform-engine:1.1.0-beta3'
testCompile 'org.junit.platform:junit-platform-runner:1.0.0-M3'
If you get an error saying
Failed to resolve: org.jetbrains.spek:spek-junit-platform-engine:1.1.0-beta3
you should be able to fix it by adding:
repositories {
...
maven { url "http://dl.bintray.com/jetbrains/spek" }
}
To run the tests annotate the test class with @RunWith(JUnitPlatform::class) and choose to run it with JUnit. You can try to run this ExampleSpekTest.kt
@RunWith(JUnitPlatform::class)
class ExampleSpekTest : Spek({
val x = 2
val y = 3
given("x = $x and y = $y") {
val sum = x + y
it("should be that x + y = 5") {
assertEquals(5, sum)
}
it("should be that x - y = -1") {
val subtract = x - y
assertEquals(-1, subtract)
}
}
})
The output should looks like this:
Mockito
To use Mockito, we need to test compile the mockito lib. As we are using Kotlin we can take advantage of mockito-kotlin to make Mockito calls easier.
testCompile 'org.mockito:mockito-core:2.5.0'
testCompile "com.nhaarman:mockito-kotlin:1.1.0"
RxJava
For RxJava and RxAndroid we need to include:
compile "io.reactivex:rxjava:1.2.4"
compile "io.reactivex:rxandroid:1.2.1"
Writing the tests (and code)
For this demo let’s start with the implementation of a login feature. To make the code testable we can use the MVP pattern. So let’s create a LoginContract.
interface LoginContract { interface View {
fun showLoggedInScreen()
fun showProgress()
fun hideProgress()
fun showError()
}
interface Interactor {
fun isUserLoggedIn(): Observable<Boolean>
fun sendLoginRequest(): Observable<LoginResponse>
}
interface Presenter {
fun onLoginRequested()
}
}
Next logical step is to create LoginPresenter and start writing the tests.
But, as LoginPresenter will use RxJava, we’ll need to override schedulers to make sure that tests are being executed on Schedulers.immediate(). For this we can define and include RxSchedulersOverrideSpek like this:
class LoginPresenterTest : Spek({
include(RxSchedulersOverrideSpek)
...
While using Spek in Android Studio you might notice that grouping test definitions with keyword “on” breaks formatting of test results and marks some tests as failing.
This can be fixed by using Spek plugin for Android Studio. To install it go to File | Settings | Plugins | Install JetBrains plugin… and then search for and install Spek. You’ll need to restart the IDE after this completes.
After that, the tests output should looks like this:
However, this plugin has an inconvenience that Android project needs to be rebuilt after every change in a Spek scope. So, at the moment you need to run assembleDebugUnitTest
before running a test as otherwise you’ll get reports for the old version and might wonder why it’s not passing.
Conclusion
Spek can help you make your tests and test reports more readable. It works well with RxJava and Mockito.
Running Spek tests in Android Studio, at the time of writing this, is not straightforward and great but it is possible.
Source code of SpekDemo app is available on GitHub.