KotlinFixture
KotlinFixture is a wrapper for JavaFixture, an attempt to bring the incredibly easy usage of Mark Seemann's AutoFixture for .NET to Java.
It strives to provide a kotlin-specific API for better integration. The purpose of this project is to generate full object graphs for use in test suites.
Contents
Getting Started
<dependency>
<groupId>com.github.nylle</groupId>
<artifactId>kotlinfixture</artifactId>
<version>0.2.0</version>
<scope>test</scope>
</dependency>
Usage
Create a Fixture
val fixture = Fixture()
Autogenerated String
val result = fixture.create<String>()
Sample Result
String: "c3932f6f-59ae-43df-8ee9-8788474a3f87"
Autogenerated Number
val result = fixture.create<Int>()
Sample Result
int: -1612385443
Complex Type
val result = fixture.create<ParentDto>()
Sample Result
- ParentDto:
- id: String: "4ed0f3c4-5ea3-4dbb-b31c-f92c036af463"
- child: ChildDto:
- id: String: "c3932f6f-59ae-43df-8ee9-8788474a3f87"
- names: ArrayList:
- String: "9452541b-c6f9-4316-b254-28d00b327d0d"
- String: "52ac46e4-1b21-40c8-9213-31fc839fbdf7"
- String: "333af3f6-4ed1-4580-9cae-aaee271d7ba7"
Collection of Strings
val result: Sequence<String> = fixture.createMany<String>()
Sample Result
ArrayList:
- String: "333af3f6-4ed1-4580-9cae-aaee271d7ba7"
- String: "9452541b-c6f9-4316-b254-28d00b327d0d"
- String: "4ed0f3c4-5ea3-4dbb-b31c-f92c036af463"
Add to Collection
val collection = mutableListOf("HELLO!")
fixture.addManyTo(collection)
Sample Result
ArrayList:
- String: "HELLO!"
- String: "333af3f6-4ed1-4580-9cae-aaee271d7ba7"
- String: "9452541b-c6f9-4316-b254-28d00b327d0d"
- String: "4ed0f3c4-5ea3-4dbb-b31c-f92c036af463"
Set Public Property
val result = fixture.build<TestDto>()
.with { it.myPublicField = 123 }
.create()
Sample Result
TestDto:
- myPrivateField: String: "349a1f87-9d00-4623-89cb-3031bb84ddb3"
- myPublicField: int: 123
Set Private Field
val result = fixture.build<TestDto>()
.with("myPrivateField", "HELLO!")
.create()
Sample Result
TestDto:
- myPrivateField: String: "HELLO!"
- myPublicField: int: 26123854
Set All Fields For Type
val result = fixture.build<ParentDto>()
.with<String>("HELLO!")
.create()
Sample Result
- ParentDto:
- id: String: "HELLO!"
- child: ChildDto:
- id: String: "HELLO!"
- names: ArrayList:
- String: "HELLO!"
- String: "HELLO!"
- String: "HELLO!"
Omit Field
val result = fixture.build<TestDto>()
.without("myPrivateField")
.create()
Sample Result
TestDto:
- myPrivateField: String: null
- myPublicField: int: -128564
Omit Primitive Field
val result = fixture.build<TestDto.class>()
.without("myPublicField")
.create()
Sample Result
TestDto:
- myPrivateField: String: "349a1f87-9d00-4623-89cb-3031bb84ddb3"
- myPublicField: int: 0
Perform Multiple Operations
val child = fixture.create<String>()
val parent = fixture.build<ParentDto>()
.with { it.addChild(child) }
.with { it.youngestChild = child }
.create()
Sample Result
ParentDto:
- children: ArrayList:
- String: "710ba467-01a7-4bcc-b880-84eda5458989"
- String: "9452541b-c6f9-4316-b254-28d00b327d0d"
- String: "4ed0f3c4-5ea3-4dbb-b31c-f92c036af463"
- String: "349a1f87-9d00-4623-89cb-3031bb84ddb3"
- youngestChild: String: "349a1f87-9d00-4623-89cb-3031bb84ddb3"
Generics
val result = fixture.create<Optional<String>>();
Constructor
There might be some cases when you want to create an object not by instantiating it and setting all fields, but by calling one of its constructors and feeding it random values.
val result = fixture.construct<String>()
Keep in mind that only public constructors are allowed.
Configuration
The values below are the default values, used when no configuration is provided.
val config = Configuration.configure()
.collectionSizeRange(2, 10)
.streamSize(3)
.usePositiveNumbersOnly(false)
.clock(Clock.fixed(Instant.now(), ZoneOffset.UTC));
val fixture = Fixture(config);
collectionSizeRange
determines the range from which a random collection size will be picked when creating any collection, map or arraystreamSize
determines the number of objects to be returned when usingSequence<T> Fixture.createMany<T>
usePositiveNumbersOnly
defines whether to generate only positive numbers including 0 forshort
,int
,long
,float
, anddouble
clock
sets the clock to use when creating time-based values
JUnit5 Support
In order to use JUnit5 support you need to add the following dependencies if not already present.
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
Remember to also include the vintage
dependency if you still have JUnit4-tests, otherwise they won't be run.
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.5.1</version>
<scope>test</scope>
</dependency>
Inject Random Values Into Single Test
All arguments of the test-method below will be provided as a random object generated by JavaFixture.
@TestWithFixture
fun `inject parameter via method extension`(testObject: TestDto, intValue: int, genericObject: Optional<String>) {
assertThat(testObject).isInstanceOf(TestDto::class.java)
assertThat(intValue).isBetween(Int.MIN_VALUE, Int.MAX_VALUE)
assertThat(genericObject).isInstanceOf(Optional::class.java)
assertThat(genericObject).isPresent
assertThat(genericObject.get()).isInstanceOf(String::class.java)
}
You can also configure Fixture inline:
@TestWithFixture(minCollectionSize = 11, maxCollectionSize = 11, positiveNumbersOnly = true)
fun `inject parameter via method extension and configure the fixture`(testObject: TestObjectGeneric<String, ArrayList<Int>>) {
assertThat(testObject).isInstanceOf(TestObjectGeneric::class.java)
assertThat(testObject.t).isInstanceOf(String::class.java)
assertThat(testObject.u).isInstanceOf(ArrayList::class.java)
assertThat(testObject.u).hasSize(11)
assertThat(testObject.u).allMatch { it > 0 }
}