While the main configuration options should handle the majority of ways to alter how KotlinFixture generates fixtures, perhaps there is core functionality missing, or some other reason where you need finer grained control.
Of course, we would love to hear about it, to help us improve KotlinFixture so please also consider raising issues and creating PRs.
While factory
and property
generators have built-in helper functions
you can also create your own by adding extension functions to Generator
.
Generator
provides random
for you to use which can be seeded in your fixture
definition.
You also have access to fixture
for internally generating other classes.
fun Generator<Int>.odd(max: Int = Int.MAX_VALUE): Int = random.nextInt(max).let {
it + if (it % 2 == 0) 1 else 0
}
data class Person(val name: String, val age: Int)
fun Generator<Person>.person(child: Boolean): Person = Person(
name = fixture<String>(),
age = if (child) random.nextInt(random.nextInt(0, 17)) else random.nextInt(18, 95)
)
The core engine of KotlinFixture is based on a chain of Resolver
instances
which are queried in sequence. We ask each Resolver
if it handles the current input object, and it returns either a generated fixture or Unresolved.Unhandled
.
ℹ️
|
We use Unresolved as nulls are valid fixtures. |
The Resolver
interface requires the implementation of the resolve
function:
fun resolve(context: Context, obj: Any): Any?
Typically, the input object, obj
, begins as a KType
and as it passes
through the resolver chain will be changed to new values, such as a KClass
.
A recursive call to context.resolve(…)
is made with this new value for
another Resolver
to pick up.
When generating random content, use context.random
to retain the ability to provide a seeded random
.
To customise the behaviour of a Resolver
or
Decorator
, a strategy can be provided in the configuration,
and retrieved using context.strategyOrDefault(…)
.
For convenience, we add an extension function to the ConfigurationBuilder. For example, see LoggingConfiguration.