Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cooking With Spek

Cooking With Spek

Behaviour Driven Testing with Spek. A framework in Kotlin by Jetbrains.

Simon Vergauwen

September 22, 2016
Tweet

More Decks by Simon Vergauwen

Other Decks in Programming

Transcript

  1. Cooking with Spek

    View full-size slide

  2. Your host
    Simon Vergauwen
    Android developer
    [email protected]
    @vergauwen_simon

    View full-size slide

  3. A Specification Framework

    View full-size slide

  4. Cooking with Spek
    Spek
    Clean Testing
    Basic spek test
    Spek structure
    Iterative testing
    Technology Compatibility Kits (TCK)

    View full-size slide

  5. A Specification Framework

    View full-size slide

  6. Basic Spek test

    View full-size slide

  7. Coding Example
    Simple Method
    @file:JvmName("JsonUtil")

    package be.appfoundry.spekdemo.util


    import android.support.v4.util.ArrayMap

    import android.util.JsonWriter

    import java.io.StringWriter
    fun writeToJson(values: ArrayMap): String {

    // Impl

    }

    View full-size slide

  8. Coding Example
    unMock
    apply plugin: 'de.mobilej.unmock'

    unMock {

    keep "android.util.JsonWriter"

    keep "android.util.JsonScope"

    }
    classpath “de.mobilej.unmock:UnMockPlugin:0.5.0”
    https://github.com/bjoernQ/unmock-plugin

    View full-size slide

  9. Coding Example
    JUnit Test
    public class JsonUtilUnitTest {


    ArrayMap arrayMap;


    @Before

    public void setUp() throws Exception {

    arrayMap = new ArrayMap<>();

    }

    @After

    public void tearDown() throws Exception { }

    }

    View full-size slide

  10. Coding Example
    JUnit Test
    public class JsonUtilUnitTest {


    ArrayMap arrayMap;


    @Before

    public void setUp() throws Exception {

    arrayMap = new ArrayMap<>();

    }

    @Test

    public void testWriteSingleMapToJSON() {

    arrayMap.put("A","B");

    String json = JsonUtil.writeToJson(arrayMap);

    assertThat(json, containsString("\"A\":\"B\""));

    }


    @After

    public void tearDown() throws Exception { }

    }

    View full-size slide

  11. Coding Example
    JUnit Test

    View full-size slide

  12. Coding Example
    JUnit Test

    View full-size slide

  13. Coding Example
    Spek setup
    //setup kotlin
    testCompile "org.jetbrains.kotlin:kotlin-stdlib:1.0.3"

    testCompile “org.jetbrains.kotlin:kotlin-test:1.0.3”
    //setup spek

    testCompile "org.jetbrains.spek:spek-api:1.0.89"

    testCompile “org.jetbrains.spek:spek-junit-platform-engine:1.0.89"
    //setup unit platform runner

    testCompile "org.junit.platform:junit-platform-runner:1.0.0-M2"

    View full-size slide

  14. Coding Example
    Basic Spek test
    class JsonWriterUnitTest : Spek({


    })

    View full-size slide

  15. Coding Example
    Basic Spek test
    @RunWith(JUnitPlatform::class)
    class JsonWriterUnitTest : Spek({


    })

    View full-size slide

  16. Coding Example
    Basic Spek test
    @RunWith(JUnitPlatform::class)
    class JsonWriterUnitTest : Spek({

    context("A json writer") {


    }

    })

    View full-size slide

  17. Coding Example
    Basic Spek test
    @RunWith(JUnitPlatform::class)
    class JsonWriterUnitTest : Spek({

    context("A json writer") {

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))


    }

    }

    })

    View full-size slide

  18. Coding Example
    Basic Spek test
    @RunWith(JUnitPlatform::class)

    class JsonWriterUnitTest : Spek({

    context("A json writer") {

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))


    it("should contain A:B") {

    val json = writeToJson(singleValueMap)

    assertThat(json, containsString("\"A\":\"B\""))

    }

    }

    }

    })

    View full-size slide

  19. Coding Example
    Basic Spek test

    View full-size slide

  20. Spek structure

    View full-size slide

  21. Coding Example
    Spek structure
    @RunWith(JUnitPlatform::class)

    class JsonWriterUnitTest : Spek({

    context("A json writer") {

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))


    it("should contain A:B") {

    val json = writeToJson(singleValueMap)

    assertThat(json, containsString("\"A\":\"B\""))

    }

    }

    }

    })

    View full-size slide

  22. Coding Example
    Spek structure
    @RunWith(JUnitPlatform::class)

    class JsonWriterUnitTest : Spek({

    context("A json writer") {

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))


    it("should contain A:B") {

    val json = writeToJson(singleValueMap)

    assertThat(json, containsString("\"A\":\"B\""))

    }

    }

    }

    })

    View full-size slide

  23. Coding Example
    Spek structure
    @RunWith(JUnitPlatform::class)

    class JsonWriterUnitTest : Spek({

    context("A json writer") {

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))


    it("should contain A:B") {

    val json = writeToJson(singleValueMap)

    assertThat(json, containsString("\"A\":\"B\""))

    }

    }

    }

    })
    abstract class Spek(val spec: Dsl.() -> Unit)

    View full-size slide

  24. Coding Example
    Spek structure
    @RunWith(JUnitPlatform::class)

    class JsonWriterUnitTest : Spek({

    context("A json writer") {

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))


    it("should contain A:B") {

    val json = writeToJson(singleValueMap)

    assertThat(json, containsString("\"A\":\"B\""))

    }

    }

    }

    })

    View full-size slide

  25. Coding Example
    Spek structure
    @RunWith(JUnitPlatform::class)

    class JsonWriterUnitTest : Spek({

    context("A json writer") {
    beforeEach {//context beforeEach }

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))


    it("should contain A:B") {

    val json = writeToJson(singleValueMap)

    assertThat(json, containsString("\"A\":\"B\""))

    }

    }
    afterEach {//context afterEach }

    }

    })

    View full-size slide

  26. Coding Example
    Spek structure
    @RunWith(JUnitPlatform::class)

    class JsonWriterUnitTest : Spek({

    context("A json writer") {

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))


    it("should contain A:B") {

    val json = writeToJson(singleValueMap)

    assertThat(json, containsString("\"A\":\"B\""))

    }

    }

    }

    })

    View full-size slide

  27. Coding Example
    Spek structure
    @RunWith(JUnitPlatform::class)

    class JsonWriterUnitTest : Spek({

    context("A json writer") {

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))

    beforeEach { //given beforeEach }

    it("should contain A:B") {

    val json = writeToJson(singleValueMap)

    assertThat(json, containsString("\"A\":\"B\""))

    }
    afterEach { //given beforeEach }

    }

    }

    })

    View full-size slide

  28. Coding Example
    Spek structure
    @RunWith(JUnitPlatform::class)

    class JsonWriterUnitTest : Spek({

    context("A json writer") {
    beforeEach {//context beforeEach }

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))

    beforeEach { //given beforeEach }

    it("should contain A:B") {

    val json = writeToJson(singleValueMap)

    assertThat(json, containsString("\"A\":\"B\""))

    }
    afterEach { //given beforeEach }

    }
    afterEach {//context afterEach }

    }

    })

    View full-size slide

  29. Coding Example
    Spek structure
    @RunWith(JUnitPlatform::class)

    class JsonWriterUnitTest : Spek({

    context("A json writer") {

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))

    then("should contain A:B") {

    val json = writeToJson(singleValueMap)

    assertThat(json, containsString("\"A\":\"B\""))

    }

    }

    }

    })
    fun Dsl.then(description: String, body: () -> Unit) {

    test("then $description", body = body)

    }

    View full-size slide

  30. Coding Example
    Spek structure
    @RunWith(JUnitPlatform::class)

    class JsonWriterUnitTest : Spek({

    context("A json writer") {

    given("a single value map") {

    val singleValueMap = arrayMapOf(Pair("A", "B"))

    xit("should contain A:B",reason = "pending version 2") {

    val json = writeToJson(singleValueMap)

    assertThat(json, containsString("\"A\":\"B\""))

    }
    }

    }

    })

    View full-size slide

  31. Iterative testing

    View full-size slide

  32. Coding Example
    JUnit example
    @RunWith(Parameterized.class)

    public class MainPresenterUnitTest {


    @Parameters

    public static String[] data() {

    return new String[]{"[email protected]", "[email protected]",

    [email protected]", "@AppFoundryBE"};

    }


    public MainPresenterUnitTest(String input) {

    this.input = input;

    }


    @Before

    public void setUp() {

    mainView = mock(MainView.class);

    mainPresenter = new MainPresenter();

    mainPresenter.attachView(mainView);

    }


    @Test

    public void testIfItemIsShowAsEmail() {

    mainPresenter.processText(input);

    verify(mainView, times(1)).showItem(argThat(isA(MailItem.class)));

    }

    }

    View full-size slide

  33. Coding Example
    JUnit example
    @RunWith(Parameterized.class)

    public class MainPresenterUnitTest {


    @Parameters

    public static String[] data() {

    return new String[]{"[email protected]", "[email protected]",

    [email protected]", "@AppFoundryBE"};

    }


    public MainPresenterUnitTest(String input) {

    this.input = input;

    }


    @Before

    public void setUp() {

    mainView = mock(MainView.class);

    mainPresenter = new MainPresenter();

    mainPresenter.attachView(mainView);

    }


    @Test

    public void testIfItemIsShowAsEmail() {

    mainPresenter.processText(input);

    verify(mainView, times(1)).showItem(argThat(isA(MailItem.class)));

    }

    }

    View full-size slide

  34. Coding Example
    JUnit example
    @RunWith(Parameterized.class)

    public class MainPresenterUnitTest {


    @Parameters

    public static String[] data() {

    return new String[]{"[email protected]", "[email protected]",

    [email protected]", "@AppFoundryBE"};

    }


    public MainPresenterUnitTest(String input) {

    this.input = input;

    }


    @Before

    public void setUp() {

    mainView = mock(MainView.class);

    mainPresenter = new MainPresenter();

    mainPresenter.attachView(mainView);

    }


    @Test

    public void testIfItemIsShowAsEmail() {

    mainPresenter.processText(input);

    verify(mainView, times(1)).showItem(argThat(isA(MailItem.class)));

    }

    }

    View full-size slide

  35. Coding Example
    JUnit example
    @RunWith(Parameterized.class)

    public class MainPresenterUnitTest {


    @Parameters

    public static String[] data() {

    return new String[]{"[email protected]", "[email protected]",

    [email protected]", "@AppFoundryBE"};

    }


    public MainPresenterUnitTest(String input) {

    this.input = input;

    }


    @Before

    public void setUp() {

    mainView = mock(MainView.class);

    mainPresenter = new MainPresenter();

    mainPresenter.attachView(mainView);

    }


    @Test

    public void testIfItemIsShowAsEmail() {

    mainPresenter.processText(input);

    verify(mainView, times(1)).showItem(argThat(isA(MailItem.class)));

    }

    }

    View full-size slide

  36. Coding Example
    JUnit example

    View full-size slide

  37. Coding Example
    Iterative testing
    @RunWith(JUnitPlatform::class)

    class MainPresenterSpekTest : Spek({

    describe("The MainPresenter is handling the MainView") {

    var mainPresenter = MainPresenter()

    var mainView = mock()


    beforeEach {

    mainPresenter = MainPresenter()

    mainView = mock()

    mainPresenter.attachView(mainView)

    }


    on("processing a correctly formatted email adres") {

    listOf("[email protected]", "[email protected]",

    "[email protected]", "@AppFoundryBE").forEach { email ->

    it("should show $email") {

    mainPresenter.processText(email)

    verify(mainView, times(1)).showItem(argThat(isA(MailItem::class.java)))

    }

    }

    }

    }

    })

    View full-size slide

  38. Coding Example
    Iterative testing
    @RunWith(JUnitPlatform::class)

    class MainPresenterSpekTest : Spek({

    describe("The MainPresenter is handling the MainView") {

    var mainPresenter = MainPresenter()

    var mainView = mock()


    beforeEach {

    mainPresenter = MainPresenter()

    mainView = mock()

    mainPresenter.attachView(mainView)

    }


    on("processing a correctly formatted email adres") {

    listOf("[email protected]", "[email protected]",

    "[email protected]", "@AppFoundryBE").forEach { email ->

    it("should show $email") {

    mainPresenter.processText(email)

    verify(mainView, times(1)).showItem(argThat(isA(MailItem::class.java)))

    }

    }

    }

    }

    })

    View full-size slide

  39. Coding Example
    Iterative testing
    @RunWith(JUnitPlatform::class)

    class MainPresenterSpekTest : Spek({

    describe("The MainPresenter is handling the MainView") {

    var mainPresenter = MainPresenter()

    var mainView = mock()


    beforeEach {

    mainPresenter = MainPresenter()

    mainView = mock()

    mainPresenter.attachView(mainView)

    }


    on("processing a correctly formatted email adres") {

    listOf("[email protected]", "[email protected]",

    "[email protected]", "@AppFoundryBE").forEach { email ->

    it("should show $email") {

    mainPresenter.processText(email)

    verify(mainView, times(1)).showItem(argThat(isA(MailItem::class.java)))

    }

    }

    }

    }

    })

    View full-size slide

  40. Coding Example
    Iterative testing
    @RunWith(JUnitPlatform::class)

    class MainPresenterSpekTest : Spek({

    describe("The MainPresenter is handling the MainView") {

    var mainPresenter = MainPresenter()

    var mainView = mock()


    beforeEach {

    mainPresenter = MainPresenter()

    mainView = mock()

    mainPresenter.attachView(mainView)

    }


    on("processing a correctly formatted email adres") {

    listOf("[email protected]", "[email protected]",

    "[email protected]", "@AppFoundryBE").forEach { email ->

    it("should show $email") {

    mainPresenter.processText(email)

    verify(mainView, times(1)).showItem(argThat(isA(MailItem::class.java)))

    }

    }

    }

    }

    })

    View full-size slide

  41. Coding Example
    Iterative testing
    @RunWith(JUnitPlatform::class)

    class MainPresenterSpekTest : Spek({

    describe("The MainPresenter is handling the MainView") {

    var mainPresenter = MainPresenter()

    var mainView = mock()


    beforeEach {

    mainPresenter = MainPresenter()

    mainView = mock()

    mainPresenter.attachView(mainView)

    }


    on("processing a correctly formatted email adres") {

    listOf("[email protected]", "[email protected]",

    "[email protected]", "@AppFoundryBE").forEach { email ->

    it("should show $email") {

    mainPresenter.processText(email)

    verify(mainView, times(1)).showItem(argThat(isA(MailItem::class.java)))

    }

    }

    }

    }

    })

    View full-size slide

  42. Coding Example
    Iterative testing

    View full-size slide

  43. Technology Compatibility Kits (TCK)

    View full-size slide

  44. TCK
    Item
    MailItem PhoneItem TwitterItem URLItem

    View full-size slide

  45. Coding Example
    TCK
    abstract class ItemTCK(val item: Item) : Spek({

    //spek test

    })


    class URLItemTCKTest : ItemTCK(URLItem("www.appfoundry.be"))


    class TwitterItemTCKTest : ItemTCK(TwitterItem("@AppFoundryBE"))


    class MailItemTCKTest : ItemTCK(MailItem("[email protected]"))


    class PhoneItemTCKTest : ItemTCK(PhoneItem("003238719966"))

    View full-size slide

  46. Coding Example
    TCK
    abstract class ItemTCK(val factory: () -> Item) : Spek({

    val item = factory()
    //spek test

    })
    class URLItemTCKTest : ItemTCK({ URLItem("www.appfoundry.be") })


    class TwitterItemTCKTest : ItemTCK({ TwitterItem("@AppFoundryBE") })


    class MailItemTCKTest : ItemTCK({ MailItem("[email protected]") })


    class PhoneItemTCKTest : ItemTCK({ PhoneItem("003238719966") })

    View full-size slide

  47. Coding Example
    TCK
    @RunWith(PowerMockRunner::class)

    @PowerMockRunnerDelegate(JUnitPlatform::class)

    @PrepareForTest(ContextCompat::class)

    abstract class ItemTCK(val factory: () -> Item) : Spek({

    val item = factory()

    describe("handling an item object") {

    val context = mock()

    val drawable = mock()

    beforeEach {

    mockStatic(ContextCompat::class.java)

    whenever(ContextCompat.getDrawable(any(), any()))

    .thenReturn(drawable)

    }


    it("should never have a null name") {

    assertThat(item.name, notNullValue())

    }

    it("should always have a color id") {

    assertThat(item.itemColorId, isA(Int::class.java))

    }

    it("should always return a drawable") {

    assertThat(item.getIcon(context), equalTo(drawable))

    }

    }

    })

    View full-size slide

  48. Coding Example
    TCK
    @RunWith(PowerMockRunner::class)

    @PowerMockRunnerDelegate(JUnitPlatform::class)

    @PrepareForTest(ContextCompat::class)

    abstract class ItemTCK(val factory: () -> Item) : Spek({

    val item = factory()

    describe("handling an item object") {

    val context = mock()

    val drawable = mock()

    beforeEach {

    PowerMock.mockStatic(ContextCompat::class.java)

    whenever(ContextCompat.getDrawable(any(), any()))

    .thenReturn(drawable)

    }


    it("should never have a null name") {

    assertThat(item.name, notNullValue())

    }

    it("should always have a color id") {

    assertThat(item.itemColorId, isA(Int::class.java))

    }

    it("should always return a drawable") {

    assertThat(item.getIcon(context), equalTo(drawable))

    }

    }

    })

    View full-size slide

  49. Coding Example
    TCK
    @RunWith(PowerMockRunner::class)

    @PowerMockRunnerDelegate(JUnitPlatform::class)

    @PrepareForTest(ContextCompat::class)

    abstract class ItemTCK(val factory: () -> Item) : Spek({

    val item = factory()

    describe("handling an item object") {

    val context = mock()

    val drawable = mock()

    beforeEach {

    mockStatic(ContextCompat::class.java)

    whenever(ContextCompat.getDrawable(any(), any()))

    .thenReturn(drawable)

    }


    it("should never have a null name") {

    assertThat(item.name, notNullValue())

    }

    it("should always have a color id") {

    assertThat(item.itemColorId, isA(Int::class.java))

    }

    it("should always return a drawable") {

    assertThat(item.getIcon(context), equalTo(drawable))

    }

    }

    })

    View full-size slide

  50. Simplify your tests

    View full-size slide

  51. Coding Example
    Simple Rx function
    fun doSomeRxing(): Observable =

    Observable.just(1L).observeOn(AndroidSchedulers.mainThread())

    View full-size slide

  52. Coding Example
    Simple Rx function
    java.lang.ExceptionInInitializerError
    at rx.android.schedulers.AndroidSchedulers.mainThread(AndroidSchedulers.java:39)
    at be.appfoundry.spekdemo.util.RxMethodKt.doSomeRxing(RxMethod.kt:8)
    at be.appfoundry.spekdemo.util.RxTest$1$1$2.invoke(RxTest.kt:22)
    at be.appfoundry.spekdemo.util.RxTest$1$1$2.invoke(RxTest.kt:16)
    at org.jetbrains.spek.engine.Scope$Test.execute(Scope.kt:110)
    at org.jetbrains.spek.engine.Scope$Test.execute(Scope.kt:83)
    ...


    Caused by: java.lang.RuntimeException: Method getMainLooper in android.os.Looper not
    mocked. See http://g.co/androidstudio/not-mocked for details.
    at android.os.Looper.getMainLooper(Looper.java)
    at rx.android.schedulers.AndroidSchedulers
    $MainThreadSchedulerHolder.(AndroidSchedulers.java:31)
    ... 32 more

    View full-size slide

  53. Coding Example
    JUnit rule for Rx
    public class RxJavaResetRule implements TestRule {

    @Override

    public Statement apply(final Statement base, final Description description) {


    }
    }

    View full-size slide

  54. Coding Example
    JUnit rule for Rx
    public class RxJavaResetRule implements TestRule {

    @Override

    public Statement apply(final Statement base, final Description description) {

    return new Statement() {

    @Override

    public void evaluate() throws Throwable {

    //@Before


    base.evaluate();


    //@After

    } 

    };

    }
    }

    View full-size slide

  55. Coding Example
    JUnit rule for Rx
    public class RxJavaResetRule implements TestRule {

    @Override

    public Statement apply(final Statement base, final Description description) {

    return new Statement() {

    @Override

    public void evaluate() throws Throwable {

    //@Before

    RxJavaPlugins.getInstance().reset();

    RxJavaPlugins.getInstance().registerSchedulersHook(rxJavaHook);


    RxAndroidPlugins.getInstance().reset();

    RxAndroidPlugins.getInstance().registerSchedulersHook(rxAndroidHook);


    base.evaluate();


    //@After

    RxJavaPlugins.getInstance().reset();

    RxAndroidPlugins.getInstance().reset();

    } 

    };

    }
    //rxJavaHook & rxAndroidHook def
    }

    View full-size slide

  56. Coding Example
    JUnit rule for Rx
    RxJavaSchedulersHook rxJavaSchedulersHook = new RxJavaSchedulersHook(){

    @Override

    public Scheduler getComputationScheduler() {

    return Schedulers.immediate();

    }


    @Override

    public Scheduler getNewThreadScheduler() {

    return Schedulers.immediate();

    }


    @Override

    public Scheduler getIOScheduler() {

    return Schedulers.immediate();

    }

    };


    RxAndroidSchedulersHook rxAndroidSchedulersHook = new RxAndroidSchedulersHook(){

    @Override

    public Scheduler getMainThreadScheduler() {

    return Schedulers.immediate();

    }

    };

    View full-size slide

  57. Coding Example
    JUnit rule for Rx
    public class RxUnitTest {

    @Rule

    public RxJavaResetRule rxJavaResetRule = new RxJavaResetRule();


    TestSubscriber testSubscriber;


    @Before

    public void setUp() {

    testSubscriber = new TestSubscriber<>();

    }


    @Test

    public void testRx() {

    RxMethodKt.doSomeRxing().subscribe(testSubscriber);


    assertThat(testSubscriber,

    allOf(onNextEvents(hasSize(1)),
    onNextEvents(hasItem(1L)),

    hasNoErrors(),

    isCompleted()));

    }

    }

    View full-size slide

  58. Coding Example
    JUnit rule for Rx
    public class RxUnitTest {

    @Rule

    public RxJavaResetRule rxJavaResetRule = new RxJavaResetRule();


    TestSubscriber testSubscriber;


    @Before

    public void setUp() {

    testSubscriber = new TestSubscriber<>();

    }


    @Test

    public void testRx() {

    RxMethodKt.doSomeRxing().subscribe(testSubscriber);


    assertThat(testSubscriber,

    allOf(onNextEvents(hasSize(1)),
    onNextEvents(hasItem(1L)),

    hasNoErrors(),

    isCompleted()));

    }

    }

    View full-size slide

  59. Coding Example
    JUnit rule for Rx
    public class RxUnitTest {

    @Rule

    public RxJavaResetRule rxJavaResetRule = new RxJavaResetRule();


    TestSubscriber testSubscriber;


    @Before

    public void setUp() {

    testSubscriber = new TestSubscriber<>();

    }


    @Test

    public void testRx() {

    RxMethodKt.doSomeRxing().subscribe(testSubscriber);


    assertThat(testSubscriber,

    allOf(onNextEvents(hasSize(1)),
    onNextEvents(hasItem(1L)),

    hasNoErrors(),

    isCompleted()));

    }

    }

    View full-size slide

  60. Coding Example
    Junit rule in Spek
    @RunWith(JUnitPlatform::class)

    class RxTest : Spek({

    on("testing something observed by an android schedulers") {

    var testSubscriber = TestSubscriber()

    beforeEach { testSubscriber = TestSubscriber() }

    }

    })

    View full-size slide

  61. Coding Example
    Junit rule in Spek
    @RunWith(JUnitPlatform::class)

    class RxTest : Spek({

    on("testing something observed by an android schedulers") {

    var testSubscriber = TestSubscriber()

    beforeEach { testSubscriber = TestSubscriber() }


    it("should be easily tested in unit test") {

    doSomeRxing().subscribe(testSubscriber)

    assertThat(testSubscriber,

    allOf(hasNoErrors(),

    onNextEvents(hasSize(1)),

    onNextEvents(hasItem(1L)),

    isCompleted()))

    }

    }

    })

    View full-size slide

  62. Coding Example
    Simple Rx function
    inline fun Dsl.rxGroup(description: String, pending: Pending = Pending.No,

    crossinline body: Dsl.() -> Unit) {


    group(description, pending) {

    }

    }

    View full-size slide

  63. Coding Example
    Simple Rx function
    inline fun Dsl.rxGroup(description: String, pending: Pending = Pending.No,

    crossinline body: Dsl.() -> Unit) {


    group(description, pending) {

    beforeEach {

    RxJavaPlugins.getInstance().reset()

    RxJavaPlugins.getInstance().registerSchedulersHook(rxJavaHook)


    RxAndroidPlugins.getInstance().reset()

    RxAndroidPlugins.getInstance().registerSchedulersHook(rxAndroidHook)

    }


    body()


    afterEach {

    RxJavaPlugins.getInstance().reset()


    RxAndroidPlugins.getInstance().reset()

    }

    }

    }

    View full-size slide

  64. Coding Example
    Simple Rx function
    inline fun Dsl.rxGroup(description: String, pending: Pending = Pending.No,

    crossinline body: Dsl.() -> Unit) {


    group(description, pending) {

    beforeEach {

    RxJavaPlugins.getInstance().reset()

    RxJavaPlugins.getInstance().registerSchedulersHook(rxJavaHook)


    RxAndroidPlugins.getInstance().reset()

    RxAndroidPlugins.getInstance().registerSchedulersHook(rxAndroidHook)

    }


    body()


    afterEach {

    RxJavaPlugins.getInstance().reset()


    RxAndroidPlugins.getInstance().reset()

    }

    }

    }
    inline fun Dsl.onRx(description: String, crossinline body: Dsl.() -> Unit) =

    rxGroup("on $description", body = body)

    View full-size slide

  65. Coding Example
    Simple Rx function
    @RunWith(JUnitPlatform::class)

    class RxTest : Spek({

    on("when testing something observed by an android schedulers") {

    var testSubscriber = TestSubscriber()

    beforeEach { testSubscriber = TestSubscriber() }


    it("should be easily tested in unit test") {

    doSomeRxing().subscribe(testSubscriber)

    assertThat(testSubscriber,

    allOf(hasNoErrors(),

    onNextEvents(hasSize(1)),

    onNextEvents(hasItem(1L)),

    isCompleted()))

    }

    }

    })

    View full-size slide

  66. Coding Example
    Simple Rx function
    @RunWith(JUnitPlatform::class)

    class RxTest : Spek({

    onRx("when testing something observed by an android schedulers") {

    var testSubscriber = TestSubscriber()

    beforeEach { testSubscriber = TestSubscriber() }


    it("should be easily tested in unit test") {

    doSomeRxing().subscribe(testSubscriber)

    assertThat(testSubscriber,

    allOf(hasNoErrors(),

    onNextEvents(hasSize(1)),

    onNextEvents(hasItem(1L)),

    isCompleted()))

    }

    }

    })

    View full-size slide

  67. Questions?
    Simon Vergauwen
    Android developer
    [email protected]
    @vergauwen_simon

    View full-size slide