0
votes

I'm trying to write unit tests with Kotlin + Spek framework. So far looks pretty good, but I have a problem that i have to write a lot of boilerplate code, if i want to have several Spec objects for one class i'm testing.

That's my code to illustrate the problem:

object MyFirstSpec : Spek({
    val myMock1: SomeObject1 = mock()
    val myMock2: SomeObject2 = mock()
    val myMock3: SomeObject3 = mock()
    val myMock4: SomeObject4 = mock()
    val myMock5: SomeObject5 = mock()
    val myMock6: SomeObject6 = mock()

    val myClass = MyClassToTest(myMock1, myMock2, myMock3, myMock4, myMock5, myMock6)

    given("something to test here") {
        //my test here
    }
})

object MyOtherSpec : Spek({
    val myMock1: SomeObject1 = mock()
    val myMock2: SomeObject2 = mock()
    val myMock3: SomeObject3 = mock()
    val myMock4: SomeObject4 = mock()
    val myMock5: SomeObject5 = mock()
    val myMock6: SomeObject6 = mock()

    val myClass = MyClassToTest(myMock1, myMock2, myMock3, myMock4, myMock5, myMock6)

    given("something else to test here") {
        //  my test here
    }
})

I would love to create the 'abstract' Spek, where I will define my mocks etc, and after that inherit or share it somehow across my Specs.

Is there a way to achieve that?

1

1 Answers

1
votes

Unfortunately, I didn't find the way to make the Abstract Spek or inheritance, but I've found the way to use Fixtures to achieve the desired results.

Here's my pseudo code demonstrating it:

object MySpec: Spek({
    describe("my tests with Fixtures") {
        val myMock1: SomeObject1 = mock()
        val myMock2: SomeObject2 = mock()
        val myMock3: SomeObject3 = mock()
        val myMock4: SomeObject4 = mock()
        val myMock5: SomeObject5 = mock()
        val myMock6: SomeObject6 = mock()

        val myClass = MyClassToTest(myMock1, myMock2, myMock3, myMock4, myMock5, myMock6)

        afterEachTest { 
            reset(myMock1, myMock2, myMock3, myMock4, myMock5, myMock6)
            //or we can just clear invocations, if we don't want to reset the mocks
            //clearInvocations(myMock1, myMock2, myMock3, myMock4, myMock5, myMock6)
        }

        context("my first context for testing") {
            //initialization logic here specific for this context
            val somethingSpecificHere = MySpecificLogicObject()
            beforeEachTest { 
                whenever(myMock1.doSomething()).thenReturn(someResult)
            }
            on ("calling the method i'm testing"){
                myClass.myMethod(somethingSpecificHere)

                it ("should do what expected") {
                    //verifies go here
                }
            }
        }
        context("my seconds context for testing") {
            //second context specific code
        }
    }
})

Hope it will be useful for someone, who had the same problem