Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
Test::MockModule(3)   User Contributed Perl Documentation  Test::MockModule(3)

       Test::MockModule	- Override subroutines in a module for unit testing

	       use Module::Name;
	       use Test::MockModule;

		       my $module = Test::MockModule->new('Module::Name');
		       $module->mock('subroutine', sub { ... });
		       Module::Name::subroutine(@args);	# mocked

		       #Same effect, but this will die() if other_subroutine()
		       #doesn't	already	exist, which is	often desirable.
		       $module->redefine('other_subroutine', sub { ... });

	       Module::Name::subroutine(@args);	# original subroutine

	       # Working with objects
	       use Foo;
	       use Test::MockModule;
		       my $mock	= Test::MockModule->new('Foo');
		       $mock->mock(foo => sub {	print "Foo!\n";	});

		       my $foo = Foo->new();
		       $foo->foo(); # prints "Foo!\n"

       "Test::MockModule" lets you temporarily redefine	subroutines in other
       packages	for the	purposes of unit testing.

       A "Test::MockModule" object is set up to	mock subroutines for a given
       module. The object remembers the	original subroutine so it can be
       easily restored.	This happens automatically when	all MockModule objects
       for the given module go out of scope, or	when you "unmock()" the

       new($package[, %options])
	   Returns an object that will mock subroutines	in the specified

	   If there is no $VERSION defined in $package,	the module will	be
	   automatically loaded. You can override this behaviour by setting
	   the "no_auto" option:

		   my $mock = Test::MockModule->new('Module::Name', no_auto => 1);

	   Returns the target package name for the mocked subroutines

	   Returns a boolean value indicating whether or not the subroutine is
	   currently mocked

       mock($subroutine	=> \&coderef)
	   Temporarily replaces	one or more subroutines	in the mocked module.
	   A subroutine	can be mocked with a code reference or a scalar. A
	   scalar will be recast as a subroutine that returns the scalar.

	   The following statements are	equivalent:

		   $module->mock(purge => 'purged');
		   $module->mock(purge => sub {	return 'purged'});

	   When	dealing	with references, things	behave slightly	differently.
	   The following statements are	NOT equivalent:

		   # Returns the same arrayref each time, with the localtime() at time of mocking
		   $module->mock(updated => [localtime()]);
		   # Returns a new arrayref each time, with up-to-date localtime() value
		   $module->mock(updated => sub	{ return [localtime()]});

	   The following statements are	in fact	equivalent:

		   my $array_ref = [localtime()]
		   $module->mock(updated => $array_ref)
		   $module->mock(updated => sub	{ return $array_ref });

	   However, "undef" is a special case. If you mock a subroutine	with
	   "undef" it will install an empty subroutine

		   $module->mock(purge => undef);
		   $module->mock(purge => sub {	});

	   rather than a subroutine that returns "undef":

		   $module->mock(purge => sub {	undef });

	   You can call	"mock()" for the same subroutine many times, but when
	   you call "unmock()",	the original subroutine	is restored (not the
	   last	mocked instance).


	   If you are trying to	mock a subroutine exported from	another
	   module, this	may not	behave as you initially	would expect, since
	   Test::MockModule is only mocking at the target module, not anything
	   importing that module. If you mock the local	package, or use	a
	   fully qualified function name, you will get the behavior you

		   use Test::MockModule;
		   use Test::More;
		   use POSIX qw/strftime/;

		   my $posix = Test::MockModule->new("POSIX");

		   $posix->mock("strftime", "Yesterday");
		   is strftime("%D", localtime(time)), "Yesterday", "`strftime`	was mocked successfully"; # Fails
		   is POSIX::strftime("%D", localtime(time)), "Yesterday", "`strftime` was mocked successfully"; # Succeeds

		   my $main = Test::MockModule->new("main", no_auto => 1);
		   $main->mock("strftime", "today");
		   is strftime("%D", localtime(time)), "today",	"`strftime` was	mocked successfully"; #	Succeeds

	   If you are trying to	mock a subroutine that was exported into a
	   module that you're trying to	test, rather than mocking the
	   subroutine in its originating module, you can instead mock it in
	   the module you are testing:

		   package MyModule;
		   use POSIX qw/strftime/;

		   sub minus_twentyfour
			   return strftime("%a,	%b %d, %Y", localtime(time - 86400));

		   package main;
		   use Test::More;
		   use Test::MockModule;

		   my $posix = Test::MockModule->new("POSIX");
		   $posix->mock("strftime", "Yesterday");

		   is MyModule::minus_twentyfour(), "Yesterday", "`minus-twentyfour` got mocked"; # fails

		   my $mymodule	= Test::MockModule->new("MyModule", no_auto => 1);
		   $mymodule->mock("strftime", "Yesterday");
		   is MyModule::minus_twentyfour(), "Yesterday", "`minus-twentyfour` got mocked"; # succeeds

	   The same behavior as	"mock()", but this will	preemptively check to
	   be sure that	all passed subroutines actually	exist. This is useful
	   to ensure that if a mocked module's interface changes the test
	   doesn't just	keep on	testing	a code path that no longer behaves
	   consistently	with the mocked	behavior.

	   Note	that redefine is also now checking if one of the parent
	   provides the	sub and	will not die if	it's available in the chain.

	   Returns the original	(unmocked) subroutine

       unmock($subroutine [, ...])
	   Restores the	original $subroutine. You can specify a	list of
	   subroutines to "unmock()" in	one go.

	   Restores all	the subroutines	in the package that were mocked. This
	   is automatically called when	all "Test::MockObject" objects for the
	   given package go out	of scope.

       noop($subroutine	[, ...])
	   Given a list	of subroutine names, mocks each	of them	with a no-op
	   subroutine. Handy for mocking methods you want to ignore!

	       # Neuter	a list of methods in one go
	       $module->noop('purge', 'updated');



       Current Maintainer: Geoff Franks	<>

       Original	Author:	Simon Flack <simonflk _AT_>

       Copyright 2004 Simon Flack <simonflk _AT_>.  All rights

       You may distribute under	the terms of either the	GNU General Public
       License or the Artistic License,	as specified in	the Perl README	file.

perl v5.32.1			  2021-02-28		   Test::MockModule(3)


Want to link to this manual page? Use this URL:

home | help