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.
<dependency>
<groupId>com.github.nylle</groupId>
<artifactId>kotlinfixture</artifactId>
<version>0.4.1</version>
<scope>test</scope>
</dependency>
val fixture = Fixture()
val result = fixture.create<String>()
String: "c3932f6f-59ae-43df-8ee9-8788474a3f87"
val result = fixture.create<Int>()
int: -1612385443
val result = fixture.create<ParentDto>()
- 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"
val result: Sequence<String> = fixture.createMany<String>()
ArrayList:
- String: "333af3f6-4ed1-4580-9cae-aaee271d7ba7"
- String: "9452541b-c6f9-4316-b254-28d00b327d0d"
- String: "4ed0f3c4-5ea3-4dbb-b31c-f92c036af463"
val collection = mutableListOf("HELLO!")
fixture.addManyTo(collection)
ArrayList:
- String: "HELLO!"
- String: "333af3f6-4ed1-4580-9cae-aaee271d7ba7"
- String: "9452541b-c6f9-4316-b254-28d00b327d0d"
- String: "4ed0f3c4-5ea3-4dbb-b31c-f92c036af463"
val result = fixture.build<TestDto>()
.with { it.myPublicField = 123 }
.create()
TestDto:
- myPrivateField: String: "349a1f87-9d00-4623-89cb-3031bb84ddb3"
- myPublicField: int: 123
val result = fixture.build<TestDto>()
.with("myPrivateField", "HELLO!")
.create()
TestDto:
- myPrivateField: String: "HELLO!"
- myPublicField: int: 26123854
val result = fixture.build<ParentDto>()
.with<String>("HELLO!")
.create()
- ParentDto:
- id: String: "HELLO!"
- child: ChildDto:
- id: String: "HELLO!"
- names: ArrayList:
- String: "HELLO!"
- String: "HELLO!"
- String: "HELLO!"
val result = fixture.build<TestDto>()
.without("myPrivateField")
.create()
TestDto:
- myPrivateField: String: null
- myPublicField: int: -128564
val result = fixture.build<TestDto.class>()
.without("myPublicField")
.create()
TestDto:
- myPrivateField: String: "349a1f87-9d00-4623-89cb-3031bb84ddb3"
- myPublicField: int: 0
val child = fixture.create<String>()
val parent = fixture.build<ParentDto>()
.with { it.addChild(child) }
.with { it.youngestChild = child }
.create()
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"
val result = fixture.create<Optional<String>>();
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.
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
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>
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 }
}