26

In JUnit you can use @ClassRule to annotate an static field. How can I do this in Kotlin?

I tried:

object companion {
    @ClassRule @JvmStatic
    val managedMongoDb = ...    
}

and 

object companion {
    @ClassRule @JvmField
    val managedMongoDb = ...    
}

but none of the last works because rule isn't executed.

I double checked that exactly same rule works fine without static context:

@Rule @JvmField
val managedMongoDb = ...
lujop
  • 13,504
  • 9
  • 62
  • 95
  • what the difference between first two versions? – Ruslan Mar 06 '16 at 06:13
  • One uses @JvmStatic and other JvmField. To my understand as I want to reproduce a static field the first is the one to use, but I tried also with the second. – lujop Mar 06 '16 at 14:15

1 Answers1

32

You are not using companion objects correctly. You are declaring an object (single instance of a class) called companion instead of creating a companion object inside of a class. And therefore the static fields are not created correctly.

class TestClass {
    companion object { ... }
}

Is very different than:

class TestClass { 
    object companion { ... } // this is an object declaration, not a companion object
}

Although both are valid code.

Here is a correct working example of using @ClassRule, tested in Kotlin 1.0.0:

class TestWithRule {
    companion object {
        @ClassRule @JvmField
        val resource: ExternalResource = object : ExternalResource() {
            override fun before() {
                println("ClassRule Before")
            }

            override fun after() {
                println("ClassRule After")
            }
        }
    }

    @Test fun testSomething() {
        println("Testing...")
    }
}

This outputs:

ClassRule Before
Testing...
ClassRule After

Jayson Minard
  • 84,842
  • 38
  • 184
  • 227
  • 2
    `object companion { ... }` is not an object expression but an object declaration as per https://kotlinlang.org/docs/reference/object-declarations.html. – Kirill Rakhman Mar 07 '16 at 00:41