1Test::MockModule(3)   User Contributed Perl Documentation  Test::MockModule(3)
2
3
4

NAME

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

SYNOPSIS

9               use Module::Name;
10               use Test::MockModule;
11
12               {
13                       my $module = Test::MockModule->new('Module::Name');
14                       $module->mock('subroutine', sub { ... });
15                       Module::Name::subroutine(@args); # mocked
16
17                       #Same effect, but this will die() if other_subroutine()
18                       #doesn't already exist, which is often desirable.
19                       $module->redefine('other_subroutine', sub { ... });
20               }
21
22               Module::Name::subroutine(@args); # original subroutine
23
24               # Working with objects
25               use Foo;
26               use Test::MockModule;
27               {
28                       my $mock = Test::MockModule->new('Foo');
29                       $mock->mock(foo => sub { print "Foo!\n"; });
30
31                       my $foo = Foo->new();
32                       $foo->foo(); # prints "Foo!\n"
33               }
34

DESCRIPTION

36       "Test::MockModule" lets you temporarily redefine subroutines in other
37       packages for the purposes of unit testing.
38
39       A "Test::MockModule" object is set up to mock subroutines for a given
40       module. The object remembers the original subroutine so it can be
41       easily restored. This happens automatically when all MockModule objects
42       for the given module go out of scope, or when you "unmock()" the
43       subroutine.
44

METHODS

46       new($package[, %options])
47           Returns an object that will mock subroutines in the specified
48           $package.
49
50           If there is no $VERSION defined in $package, the module will be
51           automatically loaded. You can override this behaviour by setting
52           the "no_auto" option:
53
54                   my $mock = Test::MockModule->new('Module::Name', no_auto => 1);
55
56       get_package()
57           Returns the target package name for the mocked subroutines
58
59       is_mocked($subroutine)
60           Returns a boolean value indicating whether or not the subroutine is
61           currently mocked
62
63       mock($subroutine => \&coderef)
64           Temporarily replaces one or more subroutines in the mocked module.
65           A subroutine can be mocked with a code reference or a scalar. A
66           scalar will be recast as a subroutine that returns the scalar.
67
68           The following statements are equivalent:
69
70                   $module->mock(purge => 'purged');
71                   $module->mock(purge => sub { return 'purged'});
72
73           When dealing with references, things behave slightly differently.
74           The following statements are NOT equivalent:
75
76                   # Returns the same arrayref each time, with the localtime() at time of mocking
77                   $module->mock(updated => [localtime()]);
78                   # Returns a new arrayref each time, with up-to-date localtime() value
79                   $module->mock(updated => sub { return [localtime()]});
80
81           The following statements are in fact equivalent:
82
83                   my $array_ref = [localtime()]
84                   $module->mock(updated => $array_ref)
85                   $module->mock(updated => sub { return $array_ref });
86
87           However, "undef" is a special case. If you mock a subroutine with
88           "undef" it will install an empty subroutine
89
90                   $module->mock(purge => undef);
91                   $module->mock(purge => sub { });
92
93           rather than a subroutine that returns "undef":
94
95                   $module->mock(purge => sub { undef });
96
97           You can call "mock()" for the same subroutine many times, but when
98           you call "unmock()", the original subroutine is restored (not the
99           last mocked instance).
100
101           MOCKING + EXPORT
102
103           If you are trying to mock a subroutine exported from another
104           module, this may not behave as you initially would expect, since
105           Test::MockModule is only mocking at the target module, not anything
106           importing that module. If you mock the local package, or use a
107           fully qualified function name, you will get the behavior you
108           desire:
109
110                   use Test::MockModule;
111                   use Test::More;
112                   use POSIX qw/strftime/;
113
114                   my $posix = Test::MockModule->new("POSIX");
115
116                   $posix->mock("strftime", "Yesterday");
117                   is strftime("%D", localtime(time)), "Yesterday", "`strftime` was mocked successfully"; # Fails
118                   is POSIX::strftime("%D", localtime(time)), "Yesterday", "`strftime` was mocked successfully"; # Succeeds
119
120                   my $main = Test::MockModule->new("main", no_auto => 1);
121                   $main->mock("strftime", "today");
122                   is strftime("%D", localtime(time)), "today", "`strftime` was mocked successfully"; # Succeeds
123
124           If you are trying to mock a subroutine that was exported into a
125           module that you're trying to test, rather than mocking the
126           subroutine in its originating module, you can instead mock it in
127           the module you are testing:
128
129                   package MyModule;
130                   use POSIX qw/strftime/;
131
132                   sub minus_twentyfour
133                   {
134                           return strftime("%a, %b %d, %Y", localtime(time - 86400));
135                   }
136
137                   package main;
138                   use Test::More;
139                   use Test::MockModule;
140
141                   my $posix = Test::MockModule->new("POSIX");
142                   $posix->mock("strftime", "Yesterday");
143
144                   is MyModule::minus_twentyfour(), "Yesterday", "`minus-twentyfour` got mocked"; # fails
145
146                   my $mymodule = Test::MockModule->new("MyModule", no_auto => 1);
147                   $mymodule->mock("strftime", "Yesterday");
148                   is MyModule::minus_twentyfour(), "Yesterday", "`minus-twentyfour` got mocked"; # succeeds
149
150       redefine($subroutine)
151           The same behavior as "mock()", but this will preemptively check to
152           be sure that all passed subroutines actually exist. This is useful
153           to ensure that if a mocked module's interface changes the test
154           doesn't just keep on testing a code path that no longer behaves
155           consistently with the mocked behavior.
156
157           Note that redefine is also now checking if one of the parent
158           provides the sub and will not die if it's available in the chain.
159
160       original($subroutine)
161           Returns the original (unmocked) subroutine
162
163           Here is a sample how to wrap a function with custom arguments using
164           the original subroutine.  This is useful when you cannot (do not)
165           want to alter the original code to abstract one hardcoded argument
166           pass to a function.
167
168                   package MyModule;
169
170                   sub sample {
171                           return get_path_for("/a/b/c/d");
172                   }
173
174                   sub get_path_for {
175                           ... # anything goes there...
176                   }
177
178                   package main;
179                   use Test::MockModule;
180
181                   my $mock = Test::MockModule->new("MyModule");
182                   # replace all calls to get_path_for using a different argument
183                   $mock->redefine("get_path_for", sub {
184                           return $mock->original("get_path_for")->("/my/custom/path");
185                   });
186
187                   # or
188
189                   $mock->redefine("get_path_for", sub {
190                           my $path = shift;
191                           if ( $path && $path eq "/a/b/c/d" ) {
192                                   # only alter calls with path set to "/a/b/c/d"
193                                   return $mock->original("get_path_for")->("/my/custom/path");
194                           } else { # preserve the original arguments
195                                   return $mock->original("get_path_for")->(@_);
196                           }
197                   });
198
199       unmock($subroutine [, ...])
200           Restores the original $subroutine. You can specify a list of
201           subroutines to "unmock()" in one go.
202
203       unmock_all()
204           Restores all the subroutines in the package that were mocked. This
205           is automatically called when all "Test::MockObject" objects for the
206           given package go out of scope.
207
208       noop($subroutine [, ...])
209           Given a list of subroutine names, mocks each of them with a no-op
210           subroutine. Handy for mocking methods you want to ignore!
211
212               # Neuter a list of methods in one go
213               $module->noop('purge', 'updated');
214
215       TRACE
216           A stub for Log::Trace
217
218       DUMP
219           A stub for Log::Trace
220

SEE ALSO

222       Test::MockObject::Extends
223
224       Sub::Override
225

AUTHORS

227       Current Maintainer: Geoff Franks <gfranks@cpan.org>
228
229       Original Author: Simon Flack <simonflk _AT_ cpan.org>
230
232       Copyright 2004 Simon Flack <simonflk _AT_ cpan.org>.  All rights
233       reserved
234
235       You may distribute under the terms of either the GNU General Public
236       License or the Artistic License, as specified in the Perl README file.
237
238
239
240perl v5.30.0                      2019-07-26               Test::MockModule(3)
Impressum