close
Skip to content

Fastned/kenesis

Repository files navigation

Kenesis

Test library to provide mocked values to use in different tests.

📚 Table of Contents

📦 Installation

TODO()

⚡ Usage

Generating a simple class

To generate an instance of any class that has a public constructor, just call kenesis method with your class in the type. All internal fields are going to be created with random values.

...
val myInstance = kenesis<MyClass>()
...

Generating lists

Currently Kenesis does not support generating collections on maps, we suggest using something like the following code for the time being:

val myList = listOf(
    kenesis<MyClass>(),
    kenesis<MyClass>(),
    kenesis<MyClass>(),
    ...
)

Nullable fields

By default, any nullable field will have null value when the generation happens. If this is not the behavior that you want, you can ask for the library to generate the nullable fields:

val myInstance = kenesis<ClassWithNullables>(generateNullables = true)

Default parameters

The library will use your parameter's default value when generating an instance of your class, as an example, take this class:

data class ClassWithDefaultValues(
    val string: String = "My value",
    val nullableInt: Int? = null,
)

Using Kenesis to generate an instance of this class will result in the string property having the My value value. And the nullableInt having a null value. To change this, you can do as follows:

val instance = kenesis<ClassWithDefaultValues>(useDefaultValues = false)

Now, instance.string will have a random value. While instance.nullableInt will still have a null value due to the default library behavior. For more information, check the Nullable fields section.

Single use values

If you have a specific scenario where you want a class with a bunch of random data but a few specific fields need to have a specific value you can do as follows:

val instance = kenesis<ClassWithSomeProperties>(
    customParameters = mapOf(
        ClassWithSomeProperties::customString to "Custom String",
        ClassWithSomeProperties::customInt to 456,
    )
)

In this case, instance will be generated with all it's fields random, except customString and customInt which will have the values assigned from the provided map.

ℹ️ This effect is only used for one single call of the library, subsequent calls will be fully random if no map is passed.

ℹ️ This setting option also override the Default parameter option.

Customizing the generation

In some cases you may not want the full random value Kenesis provides or in other cases your class does not have a public constructor, to solve this we provide a way to extend the built in generators.

In order to do so, you need to create a class in your test package (assuming you are using this library for testing) that implements KenesisGenerator interface.

class PointGenerator: KenesisGenerator<Point> {
  override fun generate(): Point {
    val lat = Random.nextDouble(-85.0, 85.0)
    val long = Random.nextDouble(-180.0, 180.0)
    return GeometryFactory().createPoint(Coordinate(lat, long))
  }
}

In this scenario, Point don't offer a public constructor so our library cannot automatically create it. Instead Kenesis scans the classpath for any KenesisGenerator and uses it to generate the requested type.

After creating this class, you can straight away use it to generate a Point or any class that has a Point as its constructor parameters.

The same principle can be used to override the default behavior of the library, for example limiting the range of a value generated.

Keep in mind that at the current version is not possible to customize generators per call, so once you extend one or more KenesisGenerator those will be applied to all calls of kenesis(). Also registering multiple generators while supported, will have a unpredictable effect, due to our classpath scanning, for now we cannot guarantee the priority of which one will be picked up.

🤝 Contributing

If you want to improve this library you are very welcome to do so.

Developing

While developing your improvement, if you want to validate your changes locally with another project, you need to publish a local version of the library, this can be done with the command:

./gradlew publishToMavenLocal

This command will build the project and publish it to your local Maven repository, which is by default located at ~/.m2/repository.

Then, if you want to use the library in your project, you need to add the local Maven repository to your build.gradle.kts file:

TODO()

Make sure your project includes mavenLocal() in its repositories.

The snapshot version can be found in the gradle.properties file.

Publishing

Our current pipeline automate the release step of this library and auto increment the patch version meaning that if the version in gradle.properties is X.Y.Z-SNAPSHOT, the released version will be X.Y.Z and the pipeline will auto increment the snapshot to the next patch version X.Y.Z+1.

If your changes are small fixes or improvements, no version change is required; the pipeline will handle this automatically.

If your changes add new non-breaking features, you should manually update the version in gradle.properties, resetting the patch version.

For example if the current version is 0.1.5-SNAPSHOT a new feature with non-breaking changes should be 0.2.0-SNAPSHOT

For any breaking changes, please coordinate with the library maintainers regarding major versioning.

🏗 Architecture

The project is based on the usage of reflection to provide mocked values for different types. It uses a simple interface to define the mocked values and a factory to create instances of the mocked values. The library is designed to be used in tests, so it is lightweight and easy to use.

Project structure:

  • KenesisAPI: Interface to be used by external projects.
  • core: Core functionality of the library
    • KenesisFactory: Factory to create instances of mocked values. Using random values of the specific types (defined in the configuration).
  • config: Configuration of the library. It defines the mocked values for different types and allows extending the library with new types.
    • ProviderConfiguration: provides a configure method which adds mocked values to the supported ones.
    • Provider: Abstract class which controls which values are added.
    • DefaultProviderConfiguration: Default configuration of the library. It's used by KenesisFactory
    • KenesisGenerator: An interface used for clients to extend the library functionality.
  • generators: Contains the default generators for different types.
    • DateGenerators: Generates random dates.
    • StringGenerators: Generates random strings.
  • utils: Utility classes to help with the reflection and other operations.

📄 License

This project is licensed under the Apache 2.0 License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages