Test::Mock::One - Mock the world with one object
version 0.005
use Test::Mock::One; my $mock = Test::Mock::One->new( foo => 'return value', bar => 1, hashref => \{ foo => 'bar' }, arrayref => \[ foo => 'bar' ], code => sub { return your_special_function() }, ); $mock->foo; # 'return value' $mock->bar; # 1 $mock->hashref; # { foo => bar} $mock->arrayref; # [ foo, bar ] $mock->code; # executes your_special_function $mock->no->yes->work->it; # works fine
In combination with Sub::Override
my $override = Sub::Override->new('Foo::Bar::baz', sub { Test::Mock::One(foo => 'bar') });
You now have Foo::Bar::baz that returns an object where the function foo returns bar.
Let's say you want to test a function that retrieves a user from a database and checks if it is active
Package Foo; use Moose; has schema => ( is => 'ro' ); sub check_user_in_db { my ($self, $username) = @_; my $user = $self->schema->resultset('User')->search_rs({username => $username})->first; return $user if $user->is_active; die "Unable to find user"; } # In your test my $foo = Foo->new( schema => Test::Mock::One->new( schema => { resultset => { search_rs => { first => { is_active => undef } } } }, 'X-Mock-Strict' => 1, ) ); # Is the same as above, without Strict mode $foo = Foo->new( schema => Test::Mock::One->new( is_active => undef # This doesn't work with X-Mock-Strict enabled, because # the chain schema->resultset->search_rs->first cannot be # resolved ) ); throws_ok( sub { $foo->check_user_in_db('username'); }, qr/Unable to find user/, "username isn't active" ); # A sunny day scenario would have been: my $mock = Foo->new(schema => Test::Mock::One->new()); lives_ok(sub { $mock->check_user_in_db('username')}, "We found the user");
Be able to mock many things with little code by using AUTOLOAD.
The problem this module tries to solve is to allow testing many things without having to write a monkey patch kind of solution in your test. Test::Mock::One tries to solve this by creating an object that can do "everything", and allows you to control specific behaviour. It works really well in combination with Sub::Override.
The methods copy the X-Mock attributes from their parent to themselves.
Ways to override specific behaviours
Boolean value. Undefined attributes will not be mocked and calling them makes us die.
Mock the ISA into the given class. Supported ways to mock the ISA:
'X-Mock-ISA' => 'Some::Pkg', 'X-Mock-ISA' => qr/Some::Pkg/, 'X-Mock-ISA' => [qw(Some::Pkg Other::Pkg)], 'X-Mock-ISA' => sub { return 0 }, 'X-Mock-ISA' => undef,
Tell us how to stringify the object
'X-Mock-Stringify' => 'My custom string', 'X-Mock-Stringify' => sub { return "foo" },
Returns true or false, depending on how X-Mock-Strict is set.
Sub::Override
Wesley Schwengle <waterkip@cpan.org>
This software is Copyright (c) 2017 by Wesley Schwengle.
This is free software, licensed under:
The (three-clause) BSD License
To install Test::Mock::One, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Test::Mock::One
CPAN shell
perl -MCPAN -e shell install Test::Mock::One
For more information on module installation, please visit the detailed CPAN module installation guide.