Tired of manually setup test data of Kotlin data classes or POJOs? Instantiator creates Instances of any class for you so that you can focus on writing tests instead of spending time and effort to setup test data

Overview

Instantiator

Tired of manually setup test data of Kotlin data classes or POJOs? Instantiator creates Instances of any class for you so that you can focus on writing tests instead of spending time and effort to set up test data.

This is not a mocking library. When talking about Instantiator can create an instance of any class for you, I'm referring on data class or POJOs, not mock functionality.

It doesn't use any black magic. It uses reflection and invokes the public primary constructors. If there is no public primary constructor available, then Instantiator cannot instantiate it.

Usage

Assuming you have some data structures like this

data class Person(
    val id: String,
    val firstname: String,
    val lastname: String,
    val age: Int,
    val gender: Gender
)

enum class Gender {
    MALE,
    FEMALE,
    UNDEFINED
}

fun computeFullname(p: Person): String {
    return "${p.firstname} ${p.lastname}"
}

And you want to write some (unit) tests to test some functionality you often have to manually set up some object instances just for testing. This is where Instantiator comes in: it creates such instances for you.

@Test
fun someTest() {
    val person: Person =
        instance() // instance() is Instantiator's API. It creates a new instance of Person with random values. 

    // Now that you have some random Person object 
    // you can do with it whatever you want
    val expected = "${person.firstname} ${person.lastname}"
    val fullname = computeFullname(person)
    assertEquals(expected, fullname)
}

Bonus: if you want to get an instance for each subclass of a sealed class hierarchy use instantiateSealedSubclasses() like this:

sealed class Root
data class A(i: Int) : Root()
data class B(i: Int) : Root()


sealed class NestedRoot : Root()
data class N1(i: Int) : NestedRoot()


val subclassesInstances : List<Root> = instantiateSealedSubclasses()
println(subclasses) // contains 3 instances and prints  "A, B, N1"

Supported use cases

Type Support Note and default behavior description
data class ✅️ invokes primary constructor and fills parameter with random values. This works incl. other types: i.e. data class Foo( id : Int, bar : Bar). Instantiator will also instantiate a Bar instance to eventually instantiate Foo
class ✅️ works the same as data class.
sealed class randomly creates an instance by randomly picking a subclass of the sealed class hierarchy and then instantiates this one (meaning what is written in the rows above about support for data class or class still holds). Additionally, if you want to have a full list of instances of all subclasses of a sealed class hierarchy use val subclassesInstances : List = instantiateSealedSubclasses().
sealed interface works exactly the same way as sealed class (see above).
object Objects / Singleton are supported and it will return exactly that one object instance that already exists (not instantiate via generics another instance of the same object so having 2 with different memory address).
interface ❌️ Not supported out of the box because by using reflections there is no straight forward way (apart from class path scanning which is not implemented at the moment) to find out which class implements an interface.
abstract class ❌️ same reason as for interface (see above).
enum ✅️ fully supported. It randomly picks one case and returns it.
List ✅️ List and MutableList are supported in class constructors. i.e. in instance of AdressBook can be instantiated: data class AdressBook(val persons : List) but you can also directly request an instance with val persons : List = instance().
Set ✅️ Set and MutableSet are supported in class constructors. i.e. in instance of AdressBook can be instantiated: data class AdressBook(val persons : Set) but you can also directly request an instance with val persons : Set = instance()
Map ✅️ Map and MutableMap are supported in class constructors. i.e. in instance of PhoneBook can be instantiated: data class PhoneBook(val phoneNumbers : Map) but you can also directly request an instance with val phoneBook : Map> = instance()
Collection ✅️ Collection and MutableCollection are supported in class constructors. i.e. in instance of AdressBook can be instantiated: data class AdressBook(val persons : Collection) but you can also directly request an instance with val persons : Collection> = instance()
Int ✅️ random number is returned
Long ✅️ random number is returned
Float ✅️ random number is returned
Double ✅️ random number is returned
Short ✅️ random number is returned
String ✅️ random string with default length of 10 characters is returned. Pool of chars that is used to compute random string is a..z + A..Z + 0..9.
Char ✅️ random char is returned from the following pool of chars: a..z + A..Z + 0..9.
Boolean ✅️ randomly returns true or false
Byte ✅️ randomly creates one byte and returns it

Configuration

You can configure Instantiator by passing a InstantiatorConfig instance as parameter to instance(config : InstantiatorConfig) or instantiateSealedSubclasses(config : InstantiatorConfig).

Some settings that you can set:

  • InstantiatorConfig.useDefaultArguments: Set it to true if you want that the default arguments of constructor parameters are used if provided. For example, given data class MyClass(val id : Int, val name : String = "Barbra"), if config.useDefaultArguments = true then the parametername of any instance will be name="Barbra" and only id which has no default argument set will be filled with random value. Default value of the default config is that InstantiatorConfig.useDefaultArguments = true.
  • InstantiatorConfig.useNull: Set it to true if for constructor parameters that can be null, null is actually the value. for example, given data class MyClass(val id : Int?), if config.useNull = true then instance will look like MyClass( id = null). If config.useNull = false then nullable parameters will have non null values i.e. MyClass ( id = 123). Default value of default config is InstantiatorConfig.useNull = true
You might also like...
A boiler plate that can be re-used to start android apps
A boiler plate that can be re-used to start android apps

Agile Boiler Plate The main task at the innovation labs of Avast is to find new ideas to work on, prototype these ideas, and quickly implement them. A

Makes Google play in app purchase library (BillingClient) into a flowable that can easily be used in compose world

Billy the android Our goal is to make a modern api of BillingClient so that it is easier to use in compose world. This library is still early beta and

A special view that can contain other views (called children)
A special view that can contain other views (called children)

A ViewGroup is a special view that can contain other views (called children.) The view group is the base class for layouts and views containers. There

A .NET Watch Run Configuration (dotnet-watch) that can be used in RiderA .
A .NET Watch Run Configuration (dotnet-watch) that can be used in RiderA .

A .NET Watch Run Configuration (dotnet-watch) that can be used in RiderA .NET Watch Run Configuration (dotnet-watch) that can be used in Rider

Bulletin helps you to
Bulletin helps you to "swipe" through your favorite events in the campus and gives you the perfect match for your better experience

Bulletin helps you to "swipe" through your favorite events in the campus and gives you the perfect match for your better experience. Right swipe to add event to your calendar and left swipe to view the next event.

This repository contains a simple script that lets you kill gradle and kotlin daemons.

AndroidDaemonKiller This repository contains a simple script that lets you kill gradle and kotlin daemons. After updating gradle or kotlin or checking

SL4A brings scripting languages to Android by allowing you to edit and execute scripts and interactive interpreters directly on the Android device.

#Scripting Layer for Android (SL4A) SL4A brings scripting languages to Android by allowing you to edit and execute scripts and interactive interpreter

An application for runners and cyclists. Allows you to monitor your physical activity, weight and receive reminders about workouts.

An application for runners and cyclists. Allows you to monitor your physical activity, weight and receive reminders about workouts.

Make your IDE play Wilhelm Scream effect when you are using unsafe !! operator in Kotlin

Make your IDE play Wilhelm Scream effect when you are using unsafe !! operator in Kotlin

Comments
  • Make random provider configurable

    Make random provider configurable

    What was added?

    • Made random provider configurable, e.g InstantiatorConfig(random = Random(0)) The reasoning behind this PR is that a use case for this library would be something akin to snapshot-testing.
      @Test
      fun `test mapper of large object`() {
        val value = instance<SomeLargeObject>(InstantiatorConfig(random = Random(0))
      
        val mappedValue = mapper(value)
      
        snapshot.assertMatches(mappedValue);
      }
      

      But it would require the randomness to be stable across test runs.

    opened by nutgaard 1
  • Misleading useNull flag

    Misleading useNull flag

    In the InstantiatorConfig we can pass useNull as false, which I expected to fill all nullables with random values.

    Then I noticed In the Readme: If config.useNull = false then InstanceFactor will be called to decide if a null or non-null value is returned.

    digging into the code base, I found toNullableInstanceFactory which is set to use ToNullableInstanceFactoryMode.RANDOM (Randomly return null or a Random value) in all default nullable factories inside DEFAULT_INSTANCE_FACTORIES, with no way to change it except for new custom factories.

    I think useNull boolean flag should be replaced by a ToNullableInstanceFactoryMode check, as there is no way to make default nullable factories never return null.

    opened by engi2nee 5
Releases(1.0.0)
  • 1.0.0(Jul 26, 2022)

    Added support for

    • java.util.Date
    • java.time.*

    NullableInstanceFactory is now created automatically under the hood by Instantiator for a given NonNullableInstanceFactory (unless user passes explicitly in a NullableInstanceFactory for a certain type)

    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Jun 2, 2022)

    Breaking change

    • To get reproducible data (i.e. across your local machine and CI) you can now specify a (preseeded) Random that should be used to generate data. Use InstantiatorConfig.random to specify this Random. This is a breaking API change for InstanceFactoryas this Random must be used by those factories. Thanks @nutgaard #2
    Source code(tar.gz)
    Source code(zip)
  • 0.3.0(Dec 3, 2021)

  • 0.2.1(Dec 3, 2021)

  • 0.2.0(Dec 3, 2021)

    Breaking change:

    • Moved interface InstanceFactory into InstantiatorConfig so that the namespace is nicer looking: from now on InstantiatorConfig.InstanceFactory

    New:

    • Added InstanceConfig.add(vararg facotries: InstanceFactory) : InstanceConfig: This was you cann clone easily an existing InstanceConfig and add Factories.
    Source code(tar.gz)
    Source code(zip)
  • 0.1.0(Jun 16, 2021)

    First public release.

    Usage:

    val myClass : MyClass = instance()
    
    val someList : List<MyClass> = instance()
    
    val sealedClassInstances : List<RootSealedClass> = instantiateSealedSubclasses()
    
    Source code(tar.gz)
    Source code(zip)
Owner
Hannes Dorfmann
Hannes Dorfmann
****. Use the native and support library variants instead - https://developer.android.com/guide/topics/ui/look-and-feel/fonts-in-xml.html. An android library that makes it easy to add custom fonts to edittexts and textviews

Add to your project Add this line to your dependencies in build.gradle compile 'in.workarounds.typography:typography:0.0.8' Using the views There are

Workarounds 43 Nov 6, 2021
A curated list of standards, tests and benchmarks that can be used for testing and evaluating dev-tools

A curated list of standards, tests and benchmarks that can be used for testing and evaluating dev tools Contribution Add the description of the benchm

null 13 Dec 16, 2022
First submission in Belajar Fundamental Aplikasi Android Class from Dicoding Indonesia

Github User App (Submission 1) Before I explain how this application works and submission checklist, I want to say thank you to Dicoding Indonesia for

Achmad Alfiansyah 0 Dec 20, 2022
Cache support for any video player with help of single line

Video cache support for Android Table of Content Why AndroidVideoCache? Features Get started Recipes Disk cache limit Listen caching progress Providin

Alexey Danilov 5.1k Jan 6, 2023
The SSI Kit is a technology stack for enabling Self-Sovereign Identity (SSI) in any application.

Walt.ID SSI Kit The Walt.ID SSI Kit is a holistic SSI solution, with primarily focus on the European EBSI/ESSIF ecosystem. The core services are in th

walt.id 53 Dec 29, 2022
An android library for displaying fps from the choreographer and percentage of time with two or more frames dropped

DEPRECATED TinyDancer is deprecated. No more development will be taking place. Check out the Google Android developer documentation for UI performance

Friendly Robot 1.9k Jan 3, 2023
Recruitment Task App - record time which a user spends on tasks defined by himself

Recruitment-Task The purpose of this application is to record time which a user spends on tasks defined by himself. The user can add new tasks. New ta

Sylwester Zieliński 0 Feb 9, 2022
An auto IBCS API response status checking tool which test tax, address and account module

IB IBCS API Test Tool An auto IBCS API response status checking tool which test tax, address and account module. Getting Started Cd to the cloned dire

Gabriel Liu 0 Oct 15, 2021
A demo of an IOU-like agreement that can be issued, transfered and settled confidentially

The Obligation CorDapp This CorDapp comprises a demo of an IOU-like agreement that can be issued, transfered and settled confidentially. The CorDapp i

null 0 Nov 3, 2021
BlackBox - a virtual engine, it can clone and run virtual application on Android

BlackBox is a virtual engine, it can clone and run virtual application on Android, users don't have to install APK file to run the application on devices. BlackBox control all virtual applications, so you can do anything you want by using BlackBox.

null 1.6k Jan 3, 2023