Interface InstancioCartesianProductApi<T>
- Type Parameters:
T- type to create
- All Superinterfaces:
BaseApi<T>,LenientModeApi,SettingsApi,VerboseModeApi
This class supports most of the Instancio API methods, but provides additional methods for generating the Cartesian product:
with(TargetSelector, Object[])for specifying product values (see the method's Javadoc for an example)create()for obtaining the results as a list
- Since:
- 4.0.0
-
Method Summary
Modifier and TypeMethodDescriptionapplyFeed(TargetSelector selector, Feed feed) Applies the providedfeedto the specifiedselector.applyFeed(TargetSelector selector, FeedProvider provider) Creates a feed and applies it to the specifiedselector.assign(Assignment... assignments) Generates values based on given assignments.create()Returns he Cartesian product generated from values specified via thewith(TargetSelector, Object[])method as a list.filter(TargetSelector selector, FilterPredicate<V> predicate) Filters generated values using givenpredicate.generate(TargetSelector selector, GeneratorSpec<V> spec) Customises values using arbitrary generator specs.generate(TargetSelector selector, GeneratorSpecProvider<V> gen) Customises values using built-in generators provided by thegenparameter, of typeGenerators.ignore(TargetSelector selector) Specifies that a class or field should be ignored.lenient()Disables strict mode in which unused selectors trigger an error.onComplete(TargetSelector selector, OnCompleteCallback<V> callback) A callback that gets invoked after the root object has been fully populated.set(TargetSelector selector, V value) Sets a value to matching selector targets.setBlank(TargetSelector selector) Specifies that a blank object should be generated for the selected target.setModel(TargetSelector selector, Model<V> model) Applies givenmodelto the specifiedselector.subtype(TargetSelector selector, Class<?> subtype) Maps target field or class to the given subtype.supply(TargetSelector selector, Supplier<V> supplier) Supplies an object using aSupplier.supply(TargetSelector selector, Generator<V> generator) Supplies an object using aGeneratorto matching selector targets.verbose()Outputs debug information toSystem.out.with(TargetSelector selector, V... values) Sets a range of values for generating the Cartesian product.withMaxDepth(int maxDepth) Specifies the maximum depth for populating an object.withNullable(TargetSelector selector) Specifies that a field or class is nullable.withSeed(long seed) Sets the seed value for the random number generator.withSetting(SettingKey<V> key, V value) Overrides the setting for the givenkeywith the specifiedvalue.withSettings(Settings settings) Merges the specifiedSettingswith the current settings, allowing for the addition and update of settings.withUnique(TargetSelector selector) Specifies that the given selector's target(s) should have unique values.
-
Method Details
-
with
Sets a range of values for generating the Cartesian product. The results are returned as a list in lexicographical order using thecreate()method.Example:
record Widget(String type, int num) {} List<Widget> results = Instancio.ofCartesianProduct(Widget.class) .with(field(Widget::type), "FOO", "BAR", "BAZ") .with(field(Widget::num), 1, 2, 3) .create();This will produce the following list of
Widgetobjects:[Widget[type=FOO, num=1], Widget[type=FOO, num=2], Widget[type=FOO, num=3], Widget[type=BAR, num=1], Widget[type=BAR, num=2], Widget[type=BAR, num=3], Widget[type=BAZ, num=1], Widget[type=BAZ, num=2], Widget[type=BAZ, num=3]]
Limitations
A selector passed to
with()must match a single target. For example, Cartesian product cannot be generated for collection elements:record Widget(String type, int num) {} record Container(List<Widget> widgets) {} List<Container> results = Instancio.ofCartesianProduct(Container.class) .with(field(Widget::type), "FOO", "BAR", "BAZ") .with(field(Widget::num), 1, 2, 3) .create();The above will produce an error with a message:
"no item is available to emit()".- Type Parameters:
V- type of the value- Parameters:
selector- for fields and/or classes this method should be applied tovalues- the range of values to generate- Returns:
- API builder reference
- Since:
- 4.0.0
-
create
Returns he Cartesian product generated from values specified via thewith(TargetSelector, Object[])method as a list.- Returns:
- Cartesian product as a list
- Since:
- 4.0.0
-
ignore
Specifies that a class or field should be ignored.Example:
Person person = Instancio.of(Person.class) .ignore(field(Phone::getPhoneNumber)) .ignore(allStrings()) .create();will create a fully populated person, but will ignore the
getPhoneNumberfield, and all strings.Precedence
This method has higher precedence than other API methods. Once a target is ignored, no other selectors will apply. For example, the following snippet will trigger an unused selector error because
field(Phone::getNumber)is redundant:Person person = Instancio.of(Person.class) .ignore(all(Phone.class)) .set(field(Phone::getNumber), "123-45-56") .create();Usage with Java records
If
ignore()targets one of the required arguments of a record constructor, then a default value for the ignored type will be generated.Example:
record PersonRecord(String name, int age) {} PersonRecord person = Instancio.of(PersonRecord.class) .ignore(allInts()) .ignore(allStrings()) .create(); // will produce: PersonRecord[name=null, age=0] -
withNullable
Specifies that a field or class is nullable. By default, Instancio assigns non-null values to fields. If marked as nullable, Instancio will generate either a null or non-null value.Example:
Note: a type marked as nullable using this method is only nullable when declared as a field, but not as a collection element, or map key/value. For example,Person person = Instancio.of(Person.class) .withNullable(allStrings()) .withNullable(field(Person::getAddress)) .withNullable(fields().named("lastModified")) .create();withNullable(allStrings())will not generate nulls in aList<String>.- Specified by:
withNullablein interfaceBaseApi<T>- Parameters:
selector- for fields and/or classes this method should be applied to- Returns:
- API builder reference
- Since:
- 4.0.0
-
set
Sets a value to matching selector targets.Example: if
Personclass contains aList<Phone>, the following snippet will set all the country code of all phone instances to "+1".Person person = Instancio.of(Person.class) .set(field(Phone::getCountryCode), "+1") .create();Note: Instancio will not
- populate or modify objects supplied by this method
- apply other
set(),supply(), orgenerate()} methods with matching selectors to the supplied object - invoke
onComplete()callbacks on supplied instances
-
setModel
@ExperimentalApi <V> InstancioCartesianProductApi<T> setModel(TargetSelector selector, Model<V> model) Applies givenmodelto the specifiedselector.For example, given the following classes and
Model:record Foo(String value) {} record Container(Foo fooA, Foo fooB) {} Model<Foo> fooModel = Instancio.of(Foo.class) .set(field(Foo::value), "foo") .toModel();The model can be applied to a specific
Foofield declared by theContainer:Container container = Instancio.of(Container.class) .setModel(field(Container::fooA), fooModel) .create();Alternatively, to apply the model to all instances of
Foo:Container container = Instancio.of(Container.class) .setModel(all(Foo.class), fooModel) .create();Note: the following properties of the supplied model are not applied to the target object:
Settingslenient()mode- custom seed value
See the user guide for further details.
-
supply
Supplies an object using aSupplier.Example:
Person person = Instancio.of(Person.class) .supply(all(LocalDateTime.class), () -> LocalDateTime.now()) .supply(field(Address::getPhoneNumbers), () -> List.of( new PhoneNumber("+1", "123-45-67"), new PhoneNumber("+1", "345-67-89"))) .create();Note: Instancio will not
- populate or modify objects supplied by this method
- apply other
set(),supply(), orgenerate()} methods with matching selectors to the supplied object - invoke
onComplete()callbacks on supplied instances
If you require the supplied object to be populated and/or selectors to be applied, use the
BaseApi.supply(TargetSelector, Generator)method instead. -
supply
Supplies an object using aGeneratorto matching selector targets. By default, Instancio will populate uninitialised fields of the supplied object. This includes fields withnullor default primitive values.This method supports the following use cases.
Generate random objects
This method provides an instance of
Randomthat can be used to randomise generated objects. For example, if Instancio did not support creation ofjava.time.Year, it could be generated as follows:List<Year> years = Instancio.ofList(Year.class) .supply(all(Year.class), random -> Year.of(random.intRange(1900, 2000))) .create();Provide a partially initialised instance
In some cases, an object may need to be created in a certain state or instantiated using a specific constructor to be in a valid state. A partially initialised instance can be supplied using this method, and Instancio will populate remaining fields that are
null:Person person = Instancio.of(Person.class) .supply(field(Person::getAddress), random -> new Address("Springfield", "USA")) .create();This behaviour is controlled by the
AfterGeneratehint specified byGenerator.hints(). Refer to theGenerator.hints()Javadoc for details, or Custom Generators section of the user guide. -
generate
Customises values using built-in generators provided by thegenparameter, of typeGenerators.Example:
Person person = Instancio.of(Person.class) .generate(field(Person::getAge), gen -> gen.ints().range(18, 100)) .generate(all(LocalDate.class), gen -> gen.temporal().localDate().past()) .generate(field(Address::getPhoneNumbers), gen -> gen.collection().size(5)) .generate(field(Address::getCity), gen -> gen.oneOf("Burnaby", "Vancouver", "Richmond")) .create();- Specified by:
generatein interfaceBaseApi<T>- Type Parameters:
V- type of object to generate- Parameters:
selector- for fields and/or classes this method should be applied togen- provider of customisable built-in generators (also known as specs)- Returns:
- API builder reference
- Since:
- 4.0.0
- See Also:
-
generate
@ExperimentalApi <V> InstancioCartesianProductApi<T> generate(TargetSelector selector, GeneratorSpec<V> spec) Customises values using arbitrary generator specs.Example:
Person person = Instancio.of(Person.class) .generate(field(Person::getAge), Instancio.ints().range(18, 100)) .generate(all(LocalDate.class), Instancio.temporal().localDate().past()) .generate(field(Phone::getNumber), MyCustomGenerators.phones().northAmerican()) .create(); -
onComplete
<V> InstancioCartesianProductApi<T> onComplete(TargetSelector selector, OnCompleteCallback<V> callback) A callback that gets invoked after the root object has been fully populated.Example:
// Sets countryCode field on all instances of Phone to the specified value Person person = Instancio.of(Person.class) .onComplete(all(Phone.class), (Phone phone) -> phone.setCountryCode("+1")) .create();Note: callbacks are never invoked on objects provided using:
OnCompleteCallback<String> callback = (String value) -> { // do something with the value }; Person person = Instancio.of(Person.class) .set(field(Phone::getCountryCode), "+1") // The callback will not be invoked because // Phone.countryCode value was provided via set() method .onComplete(field(Phone::getCountryCode), callback) .create();- Specified by:
onCompletein interfaceBaseApi<T>- Type Parameters:
V- type of object handled by the callback- Parameters:
selector- for fields and/or classes this method should be applied tocallback- to invoke after object has been populated- Returns:
- API builder reference
- Since:
- 4.0.0
-
filter
@ExperimentalApi <V> InstancioCartesianProductApi<T> filter(TargetSelector selector, FilterPredicate<V> predicate) Filters generated values using givenpredicate. If a value is rejected, a new value will be generated, which will also be tested against thepredicate. If no value is accepted afterKeys.MAX_GENERATION_ATTEMPTS, an exception will be thrown.A simple example is to generate a list of even numbers:
List<Integer> evenNumbers = Instancio.ofList(Integer.class) .filter(allInts(), (Integer i) -> i % 2 == 0) .create();Note that customising objects using this method is less efficient than
BaseApi.generate(TargetSelector, GeneratorSpecProvider). The latter should be preferred where possible.- Specified by:
filterin interfaceBaseApi<T>- Type Parameters:
V- the type of object the predicate is evaluated against- Parameters:
selector- for fields and/or classes this method should be applied topredicate- that must be satisfied by the generated value- Returns:
- API builder reference
- Since:
- 4.6.0
- See Also:
-
setBlank
Specifies that a blank object should be generated for the selected target.A blank object has the following properties:
- value fields (strings, numbers, dates, etc) are
null - arrays, collections, and maps are empty
- nested POJOs are blank
Example:
Person person = Instancio.of(Person.class) .setBlank(field(Person::getAddress)) .create(); // Output: // Person[ // name="GNQTXA", // dateOfBirth=1988-04-09, // address=Address[street=null, city=null, country=null] // blank Address //] - value fields (strings, numbers, dates, etc) are
-
subtype
Maps target field or class to the given subtype. This can be used in the following cases:- to specify an implementation for interfaces or abstract classes
- to override default implementations used by Instancio
When Instancio encounters an interface or an abstract type it is not aware of (for example, that is not part of the JDK), it will not be able to instantiate it. This method can be used to specify an implementation to use in such cases. For example:
WidgetContainer container = Instancio.of(WidgetContainer.class) .subtype(all(AbstractWidget.class), ConcreteWidget.class) .create();Override default implementations
By default, Instancio uses certain defaults for collection classes, for example
ArrayListforList. If an alternative implementation is required, this method allows to specify it:Person person = Instancio.of(Person.class) .subtype(all(List.class), LinkedList.class) .create();will use the
LinkedListimplementation for allLists. -
applyFeed
Applies the providedfeedto the specifiedselector. Theselectortargets must be POJOs or Javarecords. Properties from thefeedwill be automatically mapped to the selected objects.For example, we can generate instances of the following record:
record Person(String firstName, String lastName, String fullName, int age, String username, String email) {}using data from a CSV file (formatted for readability):
firstName, lastName, age, username John, Doe, 24, john_doe Alice, Smith, 55, alice_s # more entries...
by defining the following feed:
@Feed.Source(resource = "persons.csv") interface PersonFeed extends Feed { @TemplateSpec("${firstName} ${lastName}") FeedSpec<String> fullName(); @GeneratedSpec(CustomEmailGenerator.class) FeedSpec<String> email(); }and applying the feed using the
all(Person.class)selector:Feed personFeed = Instancio.createFeed(PersonFeed.class); List<Person> persons = Instancio.ofList(Person.class) .applyFeed(all(Person.class), personFeed) .create();Data from the CSV will be mapped to
Personfields by matching field names to property names in the data file.- Note that
PersonFeeddoes not need to declarefirstName()andlastName()methods (they are mapped automatically). fullName()andemail()can also be mapped to thePersonobject, even though these are generated and not present in the data file.
- Note that
-
applyFeed
@ExperimentalApi InstancioCartesianProductApi<T> applyFeed(TargetSelector selector, FeedProvider provider) Creates a feed and applies it to the specifiedselector. The selector's target must be a POJO or a Javarecord. Properties from the feed will be automatically mapped to the selected object.For example, given the following CSV file (formatted for readability):
firstName, lastName, age, username John, Doe, 24, john_doe Alice, Smith, 55, alice_s # more entries...
and a record with matching properties:
class Person(String firstName, String lastName, int age, String username) {}a feed can be applied as follows:
List<Person> persons = Instancio.ofList(Person.class) .applyFeed(all(Person.class), feed -> feed.ofResource("data/persons.csv")) .create(); // Output: // [Person[firstName=John, lastName=Doe, age=24, username=john_doe], // Person[firstName=Alice, lastName=Smith, age=55, username=alice_s]] -
withUnique
Specifies that the given selector's target(s) should have unique values.Example:
record Data(int foo, int bar) {} List<Data> results = Instancio.ofList(Data.class) .size(100) .withUnique(field(Data::foo)) .create();The above snippet generates a list of
Datainstances with uniquefoovalues. Note that values will be unique across all targets that match the selector. For instance, the following usages:withUnique(allInts())withUnique(all(field(Data::foo), field(Data::bar))
would result in unique values for
fooandbarwith no overlap (i.e.fooandbarare disjoint). To generate unique values per field (with potential overlap), thewithUnique()method must be specified per field:List<Data> results = Instancio.ofList(Data.class) .size(100) .withUnique(field(Data::foo)) // e.g. { 601, 42, 573, ...} .withUnique(field(Data::bar)) // e.g. { 888, 251, 42, ...} .create();If it is impossible to generate a sufficient number of unique values after a certain number of attempts, an exception will be thrown:
List<Boolean> results = Instancio.ofList(Boolean.class) .size(10) // will fail as it's impossible to generate 10 unique booleans .withUnique(allBooleans()) .create();- Specified by:
withUniquein interfaceBaseApi<T>- Parameters:
selector- for fields and/or classes this method should be applied to- Returns:
- API builder reference
- Since:
- 4.8.0
-
assign
Generates values based on given assignments. AnAssignmentcan be created using one of the builder patterns provided by theAssignclass.Assign.valueOf(originSelector).to(destinationSelector)Assign.given(originSelector).satisfies(predicate).set(destinationSelector, value)Assign.given(originSelector, destinationSelector).set(predicate, value)
For example, the following snippet uses
Assign.given(TargetSelector, TargetSelector)to create an assignment that setsPhone.countryCodebased on the value of theAddress.countryfield:Assignment assignment = Assign.given(field(Address::getCountry), field(Phone::getCountryCode)) .set(When.isIn("Canada", "USA"), "+1") .set(When.is("Italy"), "+39") .set(When.is("Poland"), "+48") .set(When.is("Germany"), "+49"); Person person = Instancio.of(Person.class) .generate(field(Address::getCountry), gen -> gen.oneOf("Canada", "USA", "Italy", "Poland", "Germany")) .assign(assignment) .create();The above API allows specifying different values for a given origin/destination pair. An alternative for creating a conditional is provided by
Assign.given(TargetSelector). This method allows specifying different destination selectors for a given origin:Assignment shippedOrderAssignment = Assign.given(Order::getStatus) .is(OrderStatus.SHIPPED) .supply(field(Order::getDeliveryDueDate), () -> LocalDate.now().plusDays(2)); Assignment cancelledOrderAssignment = Assign.given(Order::getStatus) .is(OrderStatus.CANCELLED) .set(field(Order::getCancellationReason), "Shipping delays") .generate(field(Order::getCancellationDate), gen -> gen.temporal().instant().past()); List<Order> orders = Instancio.ofList(Order.class) .generate(all(OrderStatus.class), gen -> gen.oneOf(OrderStatus.SHIPPED, OrderStatus.CANCELLED)) .assign(shippedOrderAssignment, cancelledOrderAssignment) .create();Limitations of assignments
Using assignments has a few limitations to be aware of.
- The origin selector must match a single target.
It must not be a
SelectorGroupcreated viaSelect.all(GroupableSelector...)or primitive/wrapper selector, such asSelect.allInts() - An assignment where the origin selector's target is within a collection element must have a destination selector within the same collection element.
- Circular assignments will produce an error.
-
withMaxDepth
Specifies the maximum depth for populating an object. The root object is at depth zero. Children of the root object are at depth 1, grandchildren at depth 2, and so on.Instancio will populate values up to the maximum depth. Beyond that, values will be
nullunless the maximum depth is set to a higher value.The default maximum depth is defined by
Keys.MAX_DEPTH.Note: this method is a shorthand for:
int maxDepth = 5; Person person = Instancio.of(Person.class) .withSettings(Settings.create().set(Keys.MAX_DEPTH, maxDepth)) .create();If the maximum depth is specified using
Settingsand this method, then this method takes precedence.- Specified by:
withMaxDepthin interfaceBaseApi<T>- Parameters:
maxDepth- the maximum depth, must not be negative- Returns:
- API builder reference
- Since:
- 4.0.0
-
withSetting
Overrides the setting for the givenkeywith the specifiedvalue.- Specified by:
withSettingin interfaceSettingsApi- Type Parameters:
V- the setting value type- Parameters:
key- the setting key to overridevalue- the setting value- Returns:
- API builder reference
- Since:
- 4.3.1
- See Also:
-
withSettings
Merges the specifiedSettingswith the current settings, allowing for the addition and update of settings.Use this method to apply custom settings to override the default ones. The provided settings will be combined with the existing settings, updating any overlapping values and adding any new ones.
- Specified by:
withSettingsin interfaceSettingsApi- Parameters:
settings- the custom settings to merge with the current settings- Returns:
- API builder reference
- Since:
- 4.0.0
- See Also:
-
withSeed
Sets the seed value for the random number generator. If the seed is not specified, a random seed will be used. Specifying the seed is useful for reproducing test results. By specifying the seed value, the same random data will be generated again.Example:
// Generates a different UUID each time UUID result = Instancio.create(UUID.class); // Generates the same UUID each time UUID result = Instancio.of(UUID.class) .withSeed(1234) .create(); -
lenient
InstancioCartesianProductApi<T> lenient()Disables strict mode in which unused selectors trigger an error. In lenient mode unused selectors are simply ignored.This method is a shorthand for:
Example example = Instancio.of(Example.class) .withSetting(Keys.MODE, Mode.LENIENT) .create();- Specified by:
lenientin interfaceLenientModeApi- Returns:
- API builder reference
- Since:
- 4.0.0
-
verbose
InstancioCartesianProductApi<T> verbose()Outputs debug information toSystem.out. This includes:- current
Settings - node hierarchy, including the type and depth of each node
- seed used to create the object
Warning: this method has a significant performance impact. It is recommended to remove the call to
verbose()after troubleshooting is complete.- Specified by:
verbosein interfaceVerboseModeApi- Returns:
- API builder reference
- Since:
- 4.0.0
- current
-