Skip to content

Features

Quick reference of all Fakt capabilities.


Supported Class Types

CaseExample
Interfaces
@Fake
interface UserRepository {
    suspend fun getUser(id: String): User
}
Abstract Classes
@Fake
abstract class BaseService {
    abstract fun start(): Boolean
}
Open Classes
@Fake
open class NetworkClient {
    open suspend fun fetch(url: String): Result<String>
}
Data Classes Can't be faked
Works as parameter/return types
Sealed Classes Can't be faked
Works as parameter/return types

Type System

CaseExample
Class-Level Generics
val fake = fakeRepository<User> {
    save { item -> Result.success(Unit) }
}
Method-Level Generics
fun <T, R> transform(input: T, mapper: (T) -> R): R
Generic Constraints
interface ComparableRepository<T : Comparable<T>> {
    fun findMax(items: List<T>): T?
}
Variance
interface Producer<out T>
interface Consumer<in T>
Nullable Types
fun findUser(id: String): User? // Default: null
Result Types
fun save(): Result<Unit> // Default: Result.failure(...)
Collections
fun getAll(): List<User> // Default: emptyList()

Language Features

CaseExample
Suspend Functions
suspend fun fetch(): User // Works in runTest { }
Properties (val)
val apiUrl: String // fake.apiUrl + fake.apiUrlCalls.value.size
Properties (var)
var theme: String // getThemeCalls.value.size + setThemeCalls.value.size
Inheritance
interface UserRepo : BaseRepo { ... } // Inherits parent methods
Default Parameters
fun log(msg: String, level: LogLevel = INFO)

Call History & Verification

CaseExample
Call Counts
fake.trackCalls.value.size // Thread-safe call count
Verification DSL
fake.verifyTrack {
    assertTrue(wasCalledTimes(2))
    assertTrue(wasCalledWith("page_view"))
}
Call History
assertEquals("page_view", fake.trackCallHistory.first.event)
assertEquals(2, fake.trackCallHistory.all.size)
Property Tracking
fake.getThemeCalls.value.size
fake.setThemeCalls.value.size
Thread Safety Call history is backed by thread-safe internal state.
Configurable
@Fake(callHistory = CallHistoryMode.DISABLED)
interface Logger { ... }  // Lightweight, no tracking

Behavior Mutability

CaseExample
Immutable (Default)
@Fake  // Immutable by default
interface UserService { ... }
Mutable (Opt-In)
@Fake(mutability = MutabilityMode.MUTABLE)
interface UserRepository { ... }

val fake = fakeUserRepository { findById { User("1", "Alice") } }
fake.modify { findById { null } }  // Reconfigure mid-test
Explicit Immutable
@Fake(mutability = MutabilityMode.IMMUTABLE)
interface Logger { ... }  // Always immutable, overrides plugin default
Configurable
fakt {
    enableMutableFakes.set(true)  // All fakes mutable by default
}

@Fake(mutability = MutabilityMode.IMMUTABLE)
interface Logger { ... }  // Override: always immutable

Code Generation

CaseExample
Factory Functions
fakeUserRepository { getUser { id -> User(id, "Alice") } }
Type-Safe DSL Compiler catches type errors at build time.
Smart Defaults
  • String → ""
  • Int → 0
  • Boolean → false
  • List → emptyList()

Multi-Module

CaseExample
Test Fixtures (JVM)
plugins {
    `java-test-fixtures`
}

fakt {
    useGradleTestFixtures.set(true)
}

// Consumer:
testImplementation(testFixtures(projects.core))
Collector Module
(Experimental)
fakt {
    @OptIn(ExperimentalFaktMultiModule::class)
    collectFakesFrom(projects.core.analytics)
}
Consumer Module
dependencies {
    commonTest {
        implementation(projects.core.analyticsFakes)
    }
}

Platform Support

CaseExample
All KMP Targets ✅ JVM, Android, iOS, macOS, Linux, Windows, JS, WASM, watchOS, tvOS
Single Platform ✅ JVM-only, Android-only projects fully supported

Next Steps