Skip to content

Frequently Asked Questions

Common questions about Fakt, answered with honesty and technical context.


Stability & Safety

Is Fakt safe to use in production testing?

Short answer: Yes. Fakt is functionally stable and ready for production use in test suites.

Longer answer: Fakt follows a two-phase FIR → IR compilation architecture inspired by production compiler plugins like Metro. While the Kotlin compiler plugin API is not a stable API (marked @UnsafeApi), Fakt:

  • Generates code at compile-time with zero runtime dependencies
  • Has been tested across Kotlin 2.2.21+ and all KMP targets
  • Uses forward compatibility patterns (N+.2 version support)

Generated fakes are production-quality code that compiles to native binaries without reflection.

Compiler Plugin API Stability

The Kotlin compiler plugin API can change between Kotlin versions. Fakt is tested against each Kotlin release and updated as needed. Pin your Kotlin version in production CI/CD.


Comparison with Other Tools

Why not use MockK or Mockito?

MockK and Mockito are runtime mocking frameworks using reflection (JVM/Android only). Fakt generates fakes at compile-time using Kotlin IR:

  • ✅ Works on ALL KMP targets (iOS, Native, JS, WASM) without reflection
  • ✅ Zero runtime cost, compile-time type safety
  • ✅ Generated code you can read and debug

Use MockK/Mockito when: You need dynamic mocking or are on JVM-only projects.

Use Fakt when: Building Kotlin Multiplatform projects or want zero-runtime-cost test doubles.

See Why Fakt for detailed comparison.


How does Fakt compare to hand-written fakes?

Fakt generates the same code you’d write manually, but faster and without mistakes:

Aspect Hand-Written Fakes Fakt Fakes
Boilerplate ~50 lines per interface Auto-generated
Call tracking Manual (var count = 0) StateFlow (thread-safe)
Refactoring safety Breaks silently Breaks at compile-time
Maintenance Scales with codebase Zero maintenance
Customization Full control DSL configuration

Fakt doesn’t replace hand-written fakes for complex scenarios (stateful mocks, partial implementations). It eliminates boilerplate for the 80% case.


Feature Support

Does Fakt support generics?

Yes. Class-level, method-level, generic constraints, and variance are all supported. See Usage Guide: Generics for detailed examples.

Does Fakt support suspend functions?

Yes. Suspend functions preserve coroutine semantics. See Usage Guide: Suspend Functions for details.

Does Fakt support properties (val/var)?

Yes. Both read-only (val) and mutable (var) properties with call tracking. See Usage Guide: Properties for examples.

Can I change fake behavior after creation?

Yes, with mutable fakes. By default, Fakt generates immutable fakes where behavior is fixed at construction time. For integration tests that need mid-test reconfiguration, opt in to mutable fakes:

import com.rsicarelli.fakt.MutabilityMode

@Fake(mutability = MutabilityMode.MUTABLE)
interface UserRepository {
    fun findById(id: String): User?
}

// Create with initial behavior
val fake = fakeUserRepository {
    findById { id -> User(id, "Alice") }
}

// Reconfigure mid-test
fake.modify {
    findById { null }  // Now returns null
}

See Immutable vs Mutable for detailed usage and Plugin Configuration for project-wide settings.


When should I use mutable vs immutable fakes?

Use immutable fakes (default) for unit tests. They are safer, more predictable, and prevent accidental shared state. Create a new fake instance for each scenario.

Use mutable fakes for integration tests where:

  • The same injected fake needs to simulate state changes (e.g., database failure after success)
  • You are testing feature flag toggling or configuration changes
  • Multiple test phases need different behavior from the same dependency
Scenario Recommendation
Unit testing a single method Immutable (default)
Testing error handling branches Immutable (new fake per scenario)
Integration test with injected dependency Mutable
Simulating intermittent failures Mutable
Testing state machine transitions Mutable

See Immutable vs Mutable for an in-depth exploration of trade-offs, concurrency considerations, and recommendations.


Can I fake data classes or sealed classes?

No. Fakt only generates fakes for interfaces, abstract classes, and open classes. Data/sealed classes work fine as parameter/return types.


Performance

What about performance impact on build times?

Fakt uses intelligent caching across KMP targets. First target compilation typically adds ~40ms for 100+ interfaces. Subsequent targets (JVM, iOS, Android) hit cache and add ~1ms each.

For large projects (1000+ interfaces), expect:

  • First compilation: ~200-400ms
  • Cached targets: near-zero overhead (~1-2ms each)

Example from a real KMP project:

DISCOVERY: 1ms (100 interfaces, 21 classes)
GENERATION: 39ms (121 new fakes, avg 333µs/fake)
TOTAL: 40ms (iosArm64 first compilation)

compileKotlinJvm:     1ms (121 from cache)
compileKotlinAndroid: 1ms (121 from cache)

See Performance Guide for detailed benchmarks and telemetry configuration.


Multi-Module Projects

Does Fakt work with multi-module projects?

Yes, with experimental multi-module support:

// Producer module: :core:analytics/build.gradle.kts
@Fake
interface Analytics

// Collector module: :core:analytics-fakes/build.gradle.kts
plugins {
    id("com.rsicarelli.fakt")
}

fakt {
    @OptIn(ExperimentalFaktMultiModule::class)
    collectFakesFrom(projects.core.analytics)
}

// Consumer module: :app/build.gradle.kts
dependencies {
    commonTest {
        implementation(projects.core.analyticsFakes)
    }
}

For comprehensive documentation, see:
- Multi-Module - Architecture, setup, and implementation details
- kmp-multi-module sample - Working example

Experimental Feature

Multi-module support is marked @ExperimentalFaktMultiModule. It works but the API may change before 1.0.


Troubleshooting

For common issues and solutions, see the Troubleshooting Guide:


Contributing & Reporting Issues

How can I contribute to Fakt?

Contributions are welcome! See the Complete Contributing Guide for:
- Development environment setup
- Project structure and key areas
- Testing standards (GIVEN-WHEN-THEN pattern)
- Pull request process and CI checks
- Commit conventions

Quick ways to contribute:
1. 🐛 Report bugs
2. 💡 Suggest features - We love hearing your ideas!
3. 📖 Improve documentation
4. 🧪 Add tests or examples

Your feature requests shape our roadmap!


Where do I report bugs?

Use our Bug Report template.

Please include:
- Fakt version
- Kotlin version
- Project type (single-module, KMP, multi-module)
- Description of what’s happening vs what you expected
- Steps to reproduce
- Build logs with DEBUG logging:

fakt {
    logLevel.set(LogLevel.DEBUG)
}

- Minimal reproduction code

For KMP projects, also include Gradle version and target platforms.

See Troubleshooting Guide for diagnostic steps.


Still Have Questions?