Skip to content

KotlinFixture is the attempt to bring Mark Seemann's AutoFixture for .NET to Kotlin. Its purpose is to generate full object graphs for use in test suites with a fluent API for customising the test objects during generation.

License

Notifications You must be signed in to change notification settings

Nylle/KotlinFixture

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

35 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Test Maven Central MIT license

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.4.1</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 array
  • streamSize determines the number of objects to be returned when using Sequence<T> Fixture.createMany<T>
  • usePositiveNumbersOnly defines whether to generate only positive numbers including 0 for short, int, long, float, and double
  • 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 }
}

About

KotlinFixture is the attempt to bring Mark Seemann's AutoFixture for .NET to Kotlin. Its purpose is to generate full object graphs for use in test suites with a fluent API for customising the test objects during generation.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published