Test::Mockify::Sut - injection options for your System under test (Sut) based on Mockify
use Test::Mockify::Sut; use Test::Mockify::Verify qw ( WasCalled ); use Test::Mockify::Matcher qw ( String ); # build a new system under text my $MockifySut = Test::Mockify::Sut->new('Package::I::Like::To::Test', []); $MockifySut->mockImported('Package::Name', 'ImportedFunctionName')->when(String())->thenReturn('Hello'); $MockifySut->mockStatic('Fully::Qualified::FunctionName')->when(String())->thenReturn('Hello'); $MockifySut->mockConstructor('Package::Name', $Object);# hint: build this object also with Mockify my $PackageILikeToTest = $MockifySut->getMockObject(); $PackageILikeToTest->do_something();# all injections are used here # verify that the mocked method were called ok(WasCalled($PackageILikeToTest, 'ImportedFunctionName'), 'ImportedFunctionName was called'); done_testing();
Use Test::Mockify::Sut to create and configure Sut objects. Use Test::Mockify::Verify to verify the interactions with your mocks.
You can find a Example Project in ExampleProject
To mock methods or functions of your Sut is a really bad idea. Therefore this method throws a Error when used.
Sometimes it is not possible to inject the dependencies from the outside. This is especially the case when the package uses imports of static functions. mockImported provides the possibility to mock imported functions inside the mock.
mockImported
Unlike mockStatic is the injection with mockImported only in the mock valid.
mockStatic
package Show::Magician; use Magic::Tools qw ( Rabbit ); sub pullCylinder { shift; if(Rabbit('white')){ return 1; }else{ return 0; } } 1;
In the Test it can be mocked
package Test_Magician; use Magic::Tools qw ( Rabbit ); my $Mockify = Test::Mockify::Sut->new( 'Show::Magician', [] ); $Mockify->mockImported('Magic::Tools','Rabbit')->when(String('white'))->thenReturn(1); my $Magician = $Mockify->getMockObject(); is($Magician ->pullCylinder(), 1); Rabbit('white');# return original result 1;
It can be mixed with normal spy
spy
spyImported provides the possibility to spy imported functions inside the mock.
spyImported
Unlike spyStatic is the injection with spyImported only in the mock valid.
spyStatic
package Test_Magician; use Magic::Tools qw ( Rabbit ); my $Mockify = Test::Mockify::Sut->new( 'Show::Magician', [] ); $Mockify->spyImported('Magic::Tools','Rabbit')->when(String()); my $Magician = $Mockify->getMockObject(); is($Magician->pullCylinder(), 'SomeValue'); is(GetCallCount($Magician, 'Rabbit'), 1); 1;
Sometimes it is not possible to inject the dependencies from the outside. mockStatic provides the possibility to mock static functions inside the mock.
Attention: The mocked function is valid as long as the $Mockify is defined. If You leave the scope or set the $Mockify to undef the injected method will be released.
package Show::Magician; use Magic::Tools; sub pullCylinder { shift; if(Magic::Tools::Rabbit('black')){ return 1; }else{ return 0; } } 1;
In the Test it can be mocked like:
package Test_Magician; { # start scope my $Mockify = Test::Mockify::Sut->new( 'Show::Magician', [] ); $Mockify->mockStatic('Magic::Tools::Rabbit')->when(String('black'))->thenReturn(1); $Mockify->spy('log')->when(String()); my $Magician = $Mockify->getMockObject(); is($Magician->pullCylinder('black'), 1); is(Magic::Tools::Rabbit('black'), 1); } # end scope is(Magic::Tools::Rabbit('black'), 'someValue'); # The orignal method in in place again
Provides the possibility to spy static functions around the mock.
package Show::Magician; sub pullCylinder { shift; if(Magic::Tools::Rabbit('black')){ return 1; }else{ return 0; } } 1;
package Test_Magician; use Magic::Tools; my $Mockify = Test::Mockify::Sut->new( 'Show::Magician', [] ); $Mockify->spyStatic('Magic::Tools::Rabbit')->whenAny(); my $Magician = $Mockify->getMockObject(); $Magician->pullCylinder(); Magic::Tools::Rabbit('black'); is(GetCallCount($Magician, 'Magic::Tools::Rabbit'), 2); # count as long as $Mockify is valid 1;
It can be mixed with normal spy. For more options see, mockStatic
Sometimes it is not possible to inject the dependencies from the outside. This method gives you the posibility to override the constructor of a package where your Sut depends on. The defaut constructor is new if you need another constructor name, use the third parameter.
new
Attention: The mocked constructor is valid as long as the Mockify object is defined. If You leave the scope or set the Mockify object to undef the injected constructor will be released.
package Path::To::SUT; use Path::To::Package; sub callToAction { shift; return Path::To::Package->new()->doAction(); } 1;
package Test_SUT; { # start scope my $MockifySut = Test::Mockify::Sut->new( 'Path::To::SUT', [] ); $MockifySut->mockConstructor('Path::To::Package', $self->_createPathToPackage()); my $Test_SUT = $MockifySut->getMockObject(); is($Test_SUT->callToAction(), 'hello'); } # end scope sub _createPathToPackage{ my $self = shift; my $Mockify = Test::Mockify::Sut->new( 'Path::To::Package', [] ); $Mockify->mock('doAction')->when()->thenReturn('hello'); return $Mockify->getMockObject(); }
It can be mixed with normal spy.
Provides the actual mock object, which you can use for verification. This is code sugar for the method getMockObject.
getMockObject
my $Mockify = Test::Mockify::Sut->new( 'My::Module', [] ); my $VerificationObject = $Mockify->getVerificationObject(); ok(WasCalled($VerificationObject, 'FunctionName'));
To install Test::Mockify, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Test::Mockify
CPAN shell
perl -MCPAN -e shell install Test::Mockify
For more information on module installation, please visit the detailed CPAN module installation guide.