Condensing Tests in Kotlin : Dependencies

My current team maintains an application built using Spring and Kotlin. We have several thousand unit and integration tests. I'm a big fan of condensing code as much as possible, so long as it remains legibile. A lot of our older integration tests in particular take the following form:

@ExtendWith(SpringExtension::class)
class SomethingIntTest : TestBase() {
    @Autowired
    private lateinit var mockMvc: MockMvc
    @Autowired
    private lateinit var userHelper: UserHelper
    @Autowired
    private lateinit var somethingService: SomethingService

    @BeforeEach
    public override fun setup() {
        super.setup()
        //...
    }

Using default Kotlin formatting, the dependencies for the tests take up 3 lines each. This could be condensed by eliminating the empty lines, and possibly putting the @Autowired annotation on each line. But, there is another way to accomplish the same: constructor injection. Constructor injection isn't just limited to the production code, it can be employed in tests as well.

@ExtendWith(SpringExtension::class)
class SomethingIntTest @Autowired constructor(
    private val mockMvc: MockMvc
    private val userHelper: UserHelper
    private val somethingService: SomethingService
): TestBase() {

    @BeforeEach
    public override fun setup() {
        super.setup()
        //...
    }

Not only does this take up less vertical space - half the number of lines in this example - it also accomplishes one other thing. These dependencies are now immutable, made possible by dropping the lateinit var that is required for field injection, and replacing it with val.

Leave a Reply