.\" Automatically generated by Pod::Man 2.28 (Pod::Simple 3.28) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is turned on, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{ . if \nF \{ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2). .\" Fear. Run. Save yourself. No user-serviceable parts. . \" fudge factors for nroff and troff .if n \{\ . ds #H 0 . ds #V .8m . ds #F .3m . ds #[ \f1 . ds #] \fP .\} .if t \{\ . ds #H ((1u-(\\\\n(.fu%2u))*.13m) . ds #V .6m . ds #F 0 . ds #[ \& . ds #] \& .\} . \" simple accents for nroff and troff .if n \{\ . ds ' \& . ds ` \& . ds ^ \& . ds , \& . ds ~ ~ . ds / .\} .if t \{\ . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u" . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u' . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u' . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u' . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u' . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u' .\} . \" troff and (daisy-wheel) nroff accents .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V' .ds 8 \h'\*(#H'\(*b\h'-\*(#H' .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#] .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H' .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u' .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#] .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#] .ds ae a\h'-(\w'a'u*4/10)'e .ds Ae A\h'-(\w'A'u*4/10)'E . \" corrections for vroff .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u' .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u' . \" for low resolution devices (crt and lpr) .if \n(.H>23 .if \n(.V>19 \ \{\ . ds : e . ds 8 ss . ds o a . ds d- d\h'-1'\(ga . ds D- D\h'-1'\(hy . ds th \o'bp' . ds Th \o'LP' . ds ae ae . ds Ae AE .\} .rm #[ #] #H #V #F C .\" ======================================================================== .\" .IX Title "Test::MockModule 3pm" .TH Test::MockModule 3pm "2015-10-31" "perl v5.20.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Test::MockModule \- Override subroutines in a module for unit testing .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 2 \& use Module::Name; \& use Test::MockModule; \& \& { \& my $module = Test::MockModule\->new(\*(AqModule::Name\*(Aq); \& $module\->mock(\*(Aqsubroutine\*(Aq, sub { ... }); \& Module::Name::subroutine(@args); # mocked \& } \& \& Module::Name::subroutine(@args); # original subroutine \& \& # Working with objects \& use Foo; \& use Test::MockModule; \& { \& my $mock = Test::MockModule(\*(AqFoo\*(Aq); \& $mock\->mock(foo => sub { print "Foo!\en"; }); \& \& my $foo = Foo\->new(); \& $foo\->foo(); # prints "Foo!\en" \& } .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\f(CW\*(C`Test::MockModule\*(C'\fR lets you temporarily redefine subroutines in other packages for the purposes of unit testing. .PP A \f(CW\*(C`Test::MockModule\*(C'\fR 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 \f(CW\*(C`unmock()\*(C'\fR the subroutine. .SH "METHODS" .IX Header "METHODS" .ie n .IP "new($package[, %options])" 4 .el .IP "new($package[, \f(CW%options\fR])" 4 .IX Item "new($package[, %options])" Returns an object that will mock subroutines in the specified \f(CW$package\fR. .Sp If there is no \f(CW$VERSION\fR defined in \f(CW$package\fR, the module will be automatically loaded. You can override this behaviour by setting the \f(CW\*(C`no_auto\*(C'\fR option: .Sp .Vb 1 \& my $mock = Test::MockModule\->new(\*(AqModule::Name\*(Aq, no_auto => 1); .Ve .IP "\fIget_package()\fR" 4 .IX Item "get_package()" Returns the target package name for the mocked subroutines .IP "is_mocked($subroutine)" 4 .IX Item "is_mocked($subroutine)" Returns a boolean value indicating whether or not the subroutine is currently mocked .IP "mock($subroutine => \e&coderef)" 4 .IX Item "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. .Sp The following statements are equivalent: .Sp .Vb 2 \& $module\->mock(purge => \*(Aqpurged\*(Aq); \& $module\->mock(purge => sub { return \*(Aqpurged\*(Aq}); .Ve .Sp When dealing with references, things behave slightly differently. The following statements are \fB\s-1NOT\s0\fR equivalent: .Sp .Vb 4 \& # 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()]}); .Ve .Sp The following statements are in fact equivalent: .Sp .Vb 3 \& my $array_ref = [localtime()] \& $module\->mock(updated => $array_ref) \& $module\->mock(updated => sub { return $array_ref }); .Ve .Sp However, \f(CW\*(C`undef\*(C'\fR is a special case. If you mock a subroutine with \f(CW\*(C`undef\*(C'\fR it will install an empty subroutine .Sp .Vb 2 \& $module\->mock(purge => undef); \& $module\->mock(purge => sub { }); .Ve .Sp rather than a subroutine that returns \f(CW\*(C`undef\*(C'\fR: .Sp .Vb 1 \& $module\->mock(purge => sub { undef }); .Ve .Sp You can call \f(CW\*(C`mock()\*(C'\fR for the same subroutine many times, but when you call \&\f(CW\*(C`unmock()\*(C'\fR, the original subroutine is restored (not the last mocked instance). .Sp \&\fB\s-1MOCKING + EXPORT\s0\fR .Sp If you are trying to mock a subroutine exported from another module, this may not behave as you initialy 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 desire: .Sp .Vb 3 \& 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 .Ve .Sp 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: .Sp .Vb 2 \& 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\-tewntyfour\` got mocked"; # fails \& \& my $mymodule = Test::MockModule\->new("MyModule", no_auto => 1); \& $mymodule\->mock("strftime", "Yesterday"); \& is MyModule::minus_twentyfour(), "Yesterday", "\`minus\-tewntyfour\` got mocked"; # suceeds .Ve .IP "original($subroutine)" 4 .IX Item "original($subroutine)" Returns the original (unmocked) subroutine .IP "unmock($subroutine [, ...])" 4 .IX Item "unmock($subroutine [, ...])" Restores the original \f(CW$subroutine\fR. You can specify a list of subroutines to \&\f(CW\*(C`unmock()\*(C'\fR in one go. .IP "\fIunmock_all()\fR" 4 .IX Item "unmock_all()" Restores all the subroutines in the package that were mocked. This is automatically called when all \f(CW\*(C`Test::MockObject\*(C'\fR objects for the given package go out of scope. .SH "SEE ALSO" .IX Header "SEE ALSO" Test::MockObject::Extends .PP Sub::Override .SH "AUTHORS" .IX Header "AUTHORS" Current Maintainer: Geoff Franks .PP Original Author: Simon Flack .SH "COPYRIGHT" .IX Header "COPYRIGHT" Copyright 2004 Simon Flack . All rights reserved .PP You may distribute under the terms of either the \s-1GNU\s0 General Public License or the Artistic License, as specified in the Perl \s-1README\s0 file.