NAME
Mock::Data - Extensible toolkit for generating mock data
SYNOPSIS
my $mock= Mock::Data->new(
generators => {
# Select random element of an array
business_suffix => [qw( Inc. llc. gmbh. )],
industry => [qw( Construction Towing Landscaping )],
# Weighted random selection
surname => {
Smith => 24, Johnson => 19, Williams => 16, Brown => 14, Jones => 14,
Nelson => .4, Baker => .4, Hall => .4, Rivera => .4,
},
# All strings can be templates
business_name => [
'{surname} {industry} {business_suffix}',
'{surname} and {surname} {business_suffix}',
],
# Generate strings that match a regex
email => qr/(\w+)@(\w+)(\.com|\.org|\.net|\.co\.uk)/,
# Or just code your own generators
real_address => sub($mock) { $db->resultset("Address")->rand->single },
address_json => sub($mock) { encode_json($mock->real_address) },
},
# load plugins
plugins => ['Text'], # Mock::Data::Plugin::Text
);
# Put all your generators into a plugin for easy access
my $mock= Mock::Data->new(['MyCollection']);
# Call generators
say $mock->call('email');
say $mock->email; # uses AUTOLOAD
say $mock->wrap('email')->(); # coderef for repeated calling
# Pass parameters to generators
say $mock->words({ count => 50 });
say $mock->words(50);
say $mock->call(words => 50);
DESCRIPTION
This module is a generator of mock data. It takes good ideas seen in Data::Faker, Mock::Populate, and other similar modules, and combines them into a cohesive extensible design.
Each mock data generator is called as a method on an instance of Mock::Data
. This allows generators to store persistent state between calls. It also allows them to be configured with per-instance settings.
CONSTRUCTOR
new
$mock= Mock::Data->new(\@package_list);
$mock= Mock::Data->new({
generators => \%generator_set,
plugins => \@package_list,
});
Construct a new instance of Mock::Data. If called as a method of an object, this will clone the existing instance, applying generators on top of the set already present.
Arguments:
plugins => \@package_list
-
This lets you specify a list of packages whose generators should be pulled into the new object. The plugins may also change the class of the object returned.
generators => \%set
-
This specifies a set of generators that should be added after any generators that get added by plugins (or any that were carried over from the old instance if
new
is being called on an instance instead of on the class).
clone
$mock2= $mock->clone;
Calling clone
on a Mock::Data
instance returns a new Mock::Data
of the same class with the same plugins and a deep-clone of the "generator_state" and a shallow clone of the "generators" set. This may not have the desied effect if one of your generators is storing state outside of the "generator_state" hashref.
clone
does not take any arguments. If you wish to modify the object at the same time as cloning a previous one, call "new" on the previous object instance.
ATTRIBUTES
This module defines a minimal number of attributes, to leave most of the method namespace available for the generators themselves. All subclasses and custom generators should attempt to use the existing attributes instead of defining new ones.
generators
my $generator= $mock->generators->{$name};
$mock->generators( $new_hashref ); # clears cache, coerces values
This is a hashref of Mock::Data::Generator objects. Do not modify the contents of this attribute directly, as compiled versions of each generator are cached, but you may assign a new hashref to it.
When assigning, the values of the supplied hash will each get coerced into a generator via "coerce_generator" in Mock::Data::Util.
generator_state
sub my_generator($mock, @params) {
$mock->generator_state->{__PACKAGE__.'.something'}= $my_state;
}
This is a hashref where generators store state data. If the instance of Mock::Data is cloned, this hashref will be deep-cloned. Other hashref fields of the Mock::Data object are not deep-cloned, aside from the generators
field which is cloned one level deep.
Keys in this hash should be prefixed with either the name of the generator or name of the package the generator was implemented from.
METHODS
Note: All generators may be called as methods, thanks to AUTOLOAD
.
load_plugin
$mock= $mock->load_plugin($name);
This method loads the plugin Mock::Data::Plugin::${name}
if it was not loaded already, and performs whatever initialization that package wants to perform, which may return a completely different instance of Mock::Data
. Always use the return value and assume the initial reference is gone. If you want a clone, call $mock->new
first to clone it.
add_generators
$mock->add_generators( $name => $spec, ... )
Set one or more named generators. Arguments can be given as a hashref or a list of key/value pairs. $spec
can be a coderef, an arrayref (of options) or an instance of Mock::Data::Generator. If a previous generator existed by the same name, it will be replaced.
If the $name
of the generator is a package-qualified name, the generator is added under both the long and short name. For example, combine_generators( 'MyPlugin::gen' => \&gen )
will register \&gen as both 'MyPlugin::gen'
and an alias of 'gen'
. However, 'gen'
will only be added if it didn't already exist. This allows plugins to refer to eachother's names without collisions.
Returns $mock
, for chaining.
Use this method instead of directly modifying the generators
hashref so that this module can perform proper cache management.
combine_generators
$mock->combine_generators( $name => $spec, ... )
Same as "add_generators", but if a generator of that name already exists, replace it with a generator that returns both possible sets of results. If the old generator was a coderef, it will be replaced with a new generator that calls the old coderef 50% of the time. If the old generator and new generator are both Sets, the merged generator will be a concatenation of the sets.
Returns $mock
, for chaining.
Use this method instead of directly modifying the generators
hashref so that this module can perform proper cache management.
call
$mock->call($name, \%named_params, @positional_params);
This is a more direct way to invoke a generator. The more convenient way of calling the generator name as a method of the object uses AUTOLOAD
to call this method. The return value is whatever the generator returns.
wrap
my $sub= $mock->wrap($name, \%named_params, @positional_params);
say $sub->();
This creates an anonymous sub that wraps the complete call to the generator, including the instance of $mock
and any parameters you supply. This is intended for efficiency if you plan to make lots of calls to the generator.
EXPORTS
Mock::Data can export symbols from Mock::Data::Util. See that module for a complete reference for each function.
- uniform_set(@items)
- weighted_set($item => $weight, ...)
- charset($regex_set_notation)
- template($string)
- inflate_template($string)
- coerce_generator($specification)
- mock_data_subclass($class_or_object, @class_list)
SEE ALSO
AUTHOR
Michael Conrad <mike@nrdvana.net>
VERSION
version 0.04
COPYRIGHT AND LICENSE
This software is copyright (c) 2024 by Michael Conrad.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.