Faking concrete classes

Only concrete trees (concrete classes containing concrete classes) can be faked!

Data classes are ideal candidates for faking.

Requesting generation

You can declare that a class or function needs a specific faked data by using the @UsesFakes annotation.

@UsesFakes(User::class)
class MyTests

// and

@UsesFakes(User::class)
fun testUser() {}

Once a type appears in @UsesFakes, the processor will generate a fake function for it.

Instantiating

Once a class has been faked, you can get a new instance by the fake function:

@UsesFakes(User::class)
class MyTests {
    val user = fake<User>()
}

Here are the rules the processor uses to generate fakes:

  • Nullable values are always null.

  • Boolean values are set to false.

  • Numeric values are set to 0.

  • String values are set to empty "".

  • Other non-nullable non-primitive values are faked.

By using a data class, you can easily tweak your fakes according to your needs:

val user = fake<User>().copy(id = 42)

Providing fake instances

Classes that do not have a public constructor cannot be automatically faked. For these types, you need to provide your custom fake provider with @FakeProvider:

@FakeProvider
fun provideFakeInstant() = Instant.fromEpochSeconds(0)
There can be only one provider per type, and it needs to be a top-level function.

Generics

You can fake a Star-projected generic type with @UsesFakes:

data class NullGenData<T>(val content: T)

data class NonNullGenData<T : Any>(val content: T)

@Test
@UsesFakes(GenData::class)
fun testGenericFake() {
    val nullData = fake<NullGenData<*>>()
    assertNull(nullData.content)

    val nonNullData = fake<NonNullGenData<*>>()
    assertNonNull(nonNullData.content) // is Any
}

However, if you need a specific generic type to fake, you need to declare it in an injected class, even if you are never going to use that class.

data class GenData<T>(val content: T)

class GenFakes {
    @Fake lateinit var longData: GenData<String>
}

@Test
fun testDataOfLong() {
    val data = fake<GenData<String>>()
    assertEquals("", data.content)
}