Skip to content

Latest commit

 

History

History
130 lines (109 loc) · 3.27 KB

README.md

File metadata and controls

130 lines (109 loc) · 3.27 KB

⌨️ kotlin-test-factories

Auto-generated test factory functions for Kotlin. Works with KAPT by dynamically creating source files.

⚠️ WARNING. IntelliJ Idea has not yet got a smooth KAPT support. When target classes change, do one of the following:

  • Build the project (hit CMD+F9 or Ctrl+F9). IntelliJ has to be configured to build with Gradle.
  • Invoke the kaptTest gradle task.

🤷‍♀️ Why?

How to write a test for the name method?

data class User(
        val firstName: String, 
        val lastName: String, 
        val address: Address
) { 
    fun name(): String = "$firstName $lastName"
}

The code below looks clean...

@Test
fun name() {
    val user = User(
            firstName = "John",
            lastName = "Smith"
    )

    assertThat(user.name()).isEqualTo("John Smith")
}

...but it doesn't compile: the address constructor parameter isn't provided. Specifying a random address would make the compiler happy at the cost of developer happiness. It would only introduce noise to a perfectly fine test.

A good test should be readable, focused and define clear inputs. And so is this one.

As a workaround one can write a test factory function:

fun aUser(
        firstName: String = "",
        lastName: String = "",
        address: Address = anAddress()
): User {
    return User(
            firstName = firstName,
            lastName = lastName,
            address = address
    )
}

With a test factory User instances can be obtained by specifying relevant fields and omitting irrelevant ones. Our final test looks like this:

@Test
fun name() {
    val user = aUser(
            firstName = "John",
            lastName = "Smith"
    )

    assertThat(user.name()).isEqualTo("John Smith")
}

Job done! Here is a bummer though: writing and maintaining test factories is laborious and more boring than scraping the internet for thousands of food pictures. This library generates test factories automatically.

🏗 Usage

Add to build.gradle.kts:

plugins {
    kotlin("jvm") version "1.4.21"
    kotlin("kapt") version "1.4.21"
}

dependencies {
    testImplementation("pl.rzrz:kotlin-test-factories-core:VERSION") // annotations + support for generated factories
    kaptTest("pl.rzrz:kotlin-test-factories-generator:VERSION")      // generator
}

Create a configuration in test sources:

package com.me

@TestFactoriesConfig([
    User::class
])
interface TestFactoriesConfiguration

Now hit CMD+F9 or Ctrl+F9, or ./gradlew kaptTest to generate functions.

Write tests:

import com.me.TestFactories.aUser

class UserTest {

    @Test
    fun name() {
        val user = aUser(
                firstName = "John",
                lastName = "Smith"
        )

        assertThat(user.name()).isEqualTo("John Smith")
    }
}

📃 Features

  • Generate test factories
  • Sealed classes support
  • Default package same as config
  • Customizable package and class name
  • Support for generic types
  • Support for recursive types