NAME
Test::Mockify::Sut - injection options for your System under test (Sut) based on Mockify
SYNOPSIS
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();
DESCRIPTION
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
METHODS
mockImported
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.
Unlike mockStatic
is the injection with mockImported
only in the mock valid.
synopsis
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
spyImported
spyImported
provides the possibility to spy imported functions inside the mock.
Unlike spyStatic
is the injection with spyImported
only in the mock valid.
synopsis
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->spyImported('Magic::Tools','Rabbit')->when(String());
my $Magician = $Mockify->getMockObject();
is($Magician->pullCylinder(), 'SomeValue');
is(GetCallCount($Magician, 'Rabbit'), 1);
1;
It can be mixed with normal spy
mockStatic
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.
synopsis
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
It can be mixed with normal spy
ACKNOWLEDGEMENTS Thanks to @dbucky for this amazing idea
spyStatic
Provides the possibility to spy static functions around the mock.
synopsis
package Show::Magician;
sub pullCylinder {
shift;
if(Magic::Tools::Rabbit('black')){
return 1;
}else{
return 0;
}
}
1;
In the Test it can be mocked
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
mockConstructor
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.
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.
synopsis
package Path::To::SUT;
use Path::To::Package;
sub callToAction {
shift;
return Path::To::Package->new()->doAction();
}
1;
In the Test it can be mocked like:
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
.
getVerificationObject
Provides the actual mock object, which you can use for verification. This is code sugar for the method getMockObject
.
my $Mockify = Test::Mockify::Sut->new( 'My::Module', [] );
my $VerificationObject = $Mockify->getVerificationObject();
ok(WasCalled($VerificationObject, 'FunctionName'));