1Test2::Mock(3)        User Contributed Perl Documentation       Test2::Mock(3)
2
3
4

NAME

6       Test2::Mock - Module for managing mocked classes and instances.
7

DESCRIPTION

9       This module lets you add and override methods for any package
10       temporarily. When the instance is destroyed it will restore the package
11       to its original state.
12

SYNOPSIS

14           use Test2::Mock;
15           use MyClass;
16
17           my $mock = Test2::Mock->new(
18               track => $BOOL, # enable call tracking if desired
19               class => 'MyClass',
20               override => [
21                   name => sub { 'fred' },
22                   ...
23               ],
24               add => [
25                   is_mocked => sub { 1 }
26                   ...
27               ],
28               ...
29           );
30
31           # Unmock the 'name' sub
32           $mock->restore('name');
33
34           ...
35
36           $mock = undef; # Will remove all the mocking
37

CONSTRUCTION

METHODS

40       $mock = Test2::Mock->new(class => $CLASS, ...)
41           This will create a new instance of Test2::Mock that manages mocking
42           for the specified $CLASS.
43
44           Any "Test2::Mock" method can be used as a constructor argument,
45           each should be followed by an arrayref of arguments to be used
46           within the method. For instance the "add()" method:
47
48               my $mock = Test2::Mock->new(
49                   class => 'AClass',
50                   add => [foo => sub { 'foo' }],
51               );
52
53           is identical to this:
54
55               my $mock = Test2::Mock->new(
56                   class => 'AClass',
57               );
58               $mock->add(foo => sub { 'foo' });
59
60       $mock->track($bool)
61           Turn tracking on or off. Any sub added/overridden/set when tracking
62           is on will log every call in a hash retrievable via
63           "$mock->tracking". Changing the tracking toggle will not affect
64           subs already altered, but will affect any additional alterations.
65
66       $hashref = $mock->sub_tracking
67           The tracking data looks like this:
68
69               {
70                   sub_name => [
71                       {sub_name => $sub_name, sub_ref => $mock_subref, args => [... copy of @_ from the call ... ]},
72                       ...,
73                       ...,
74                   ],
75               }
76
77           Unlike call_tracking, this lists all calls by sub, so you can
78           choose to only look at the sub specific calls.
79
80           Please note: The hashref items with the subname and args are shared
81           with call_tracking, modifying one modifies the other, so copy
82           first!
83
84       $arrayref = $mock->call_tracking
85           The tracking data looks like this:
86
87               [
88                   {sub_name => $sub_name, sub_ref => $mock_subref, args => [... copy of @_ from the call ... ]},
89                   ...,
90                   ...,
91               ]
92
93           Unlike sub_tracking this lists all calls to any mocked sub, in the
94           order they were called. To filter by sub use sub_tracking.
95
96           Please note: The hashref items with the subname and args are shared
97           with sub_tracking, modifying one modifies the other, so copy first!
98
99       $mock->clear_sub_tracking()
100       $mock->clear_sub_tracking(\@subnames)
101           Clear tracking data. With no arguments ALL tracking data is
102           cleared. When arguments are provided then only those specific keys
103           will be cleared.
104
105       $mock->clear_call_tracking()
106           Clear all items from call_tracking.
107
108       $mock->add('symbol' => ..., 'symbol2' => ...)
109       $mock->override('symbol1' => ..., 'symbol2' => ...)
110       $mock->set('symbol1' => ..., 'symbol2' => ...)
111           "add()" and "override()" are the primary ways to add/modify methods
112           for a class. Both accept the exact same type of arguments. The
113           difference is that "override" will fail unless the symbol you are
114           overriding already exists, "add" on the other hand will fail if the
115           symbol does already exist.
116
117           "set()" was more recently added for cases where you may not know if
118           the sub already exists. These cases are rare, and set should be
119           avoided (think of it like 'no strict'). However there are valid use
120           cases, so it was added.
121
122           Note: Think of override as a push operation. If you call override
123           on the same symbol multiple times it will track that. You can use
124           "restore()" as a pop operation to go back to the previous mock.
125           "reset" can be used to remove all the mocking for a symbol.
126
127           Arguments must be a symbol name, with optional sigil, followed by a
128           new specification of the symbol. If no sigil is specified then '&'
129           (sub) is assumed. A simple example of overriding a sub:
130
131               $mock->override(foo => sub { 'overridden foo' });
132               my $val = $class->foo; # Runs our override
133               # $val is now set to 'overridden foo'
134
135           You can also simply provide a value and it will be wrapped in a sub
136           for you:
137
138               $mock->override( foo => 'foo' );
139
140           The example above will generate a sub that always returns the
141           string 'foo'.
142
143           There are three *special* values that can be used to generate
144           accessors:
145
146               $mock->add(
147                   name => 'rw',   # Generates a read/write accessor
148                   age  => 'ro',   # Generates a read only accessor
149                   size => 'wo',   # Generates a write only accessor
150               );
151
152           If you want to have a sub that actually returns one of the three
153           special strings, or that returns a coderef, you can use a hashref
154           as the spec:
155
156               my $ref = sub { 'my sub' };
157               $mock->add(
158                   rw_string => { val => 'rw' },
159                   ro_string => { val => 'ro' },
160                   wo_string => { val => 'wo' },
161                   coderef   => { val => $ref }, # the coderef method returns $ref each time
162               );
163
164           You can also override/add other symbol types, such as hash:
165
166               package Foo;
167               ...
168
169               $mock->add('%foo' => {a => 1});
170
171               print $Foo::foo{a}; # prints '1'
172
173           You can also tell mock to deduce the symbol type for the
174           add/override from the reference, rules are similar to glob
175           assignments:
176
177               $mock->add(
178                   -foo => sub { 'foo' },     # Adds the &foo sub to the package
179                   -foo => { foo => 1 },      # Adds the %foo hash to the package
180                   -foo => [ 'f', 'o', 'o' ], # Adds the @foo array to the package
181                   -foo => \"foo",            # Adds the $foo scalar to the package
182               );
183
184       $mock->restore($SYMBOL)
185           Restore the symbol to what it was before the last override. If the
186           symbol was recently added this will remove it. If the symbol has
187           been overridden multiple times this will ONLY restore it to the
188           previous state. Think of "override" as a push operation, and
189           "restore" as the pop operation.
190
191       $mock->reset($SYMBOL)
192           Remove all mocking of the symbol and restore the original symbol.
193           If the symbol was initially added then it will be completely
194           removed.
195
196       $mock->orig($SYMBOL)
197           This will return the original symbol, before any mocking. For
198           symbols that were added this will return undef.
199
200       $mock->current($SYMBOL)
201           This will return the current symbol.
202
203       $mock->reset_all
204           Remove all added symbols, and restore all overridden symbols to
205           their originals.
206
207       $mock->add_constructor($NAME => $TYPE)
208       $mock->override_constructor($NAME => $TYPE)
209           This can be used to inject constructors. The first argument should
210           be the name of the constructor. The second argument specifies the
211           constructor type.
212
213           The "hash" type is the most common, all arguments are used to
214           create a new hash that is blessed.
215
216               hash => sub  {
217                   my ($class, %params) = @_;
218                   return bless \%params, $class;
219               };
220
221           The "array" type is similar to the hash type, but accepts a list
222           instead of key/value pairs:
223
224               array => sub {
225                   my ($class, @params) = @_;
226                   return bless \@params, $class;
227               };
228
229           The "ref" type takes a reference and blesses it. This will modify
230           your original input argument.
231
232               ref => sub {
233                   my ($class, $params) = @_;
234                   return bless $params, $class;
235               };
236
237           The "ref_copy" type will copy your reference and bless the copy:
238
239               ref_copy => sub {
240                   my ($class, $params) = @_;
241                   my $type = reftype($params);
242
243                   return bless {%$params}, $class
244                       if $type eq 'HASH';
245
246                   return bless [@$params], $class
247                       if $type eq 'ARRAY';
248
249                   croak "Not sure how to construct a '$class' from '$params'";
250               };
251
252       $mock->before($NAME, sub { ... })
253           This will replace the original sub $NAME with a new sub that calls
254           your custom code just before calling the original method. The
255           return from your custom sub is ignored. Your sub and the original
256           both get the unmodified arguments.
257
258       $mock->after($NAME, sub { ... })
259           This is similar to before, except your callback runs after the
260           original code.  The return from your callback is ignored.
261
262       $mock->around($NAME, sub { ... })
263           This gives you the chance to wrap the original sub:
264
265               $mock->around(foo => sub {
266                   my $orig = shift;
267                   my $self = shift;
268                   my (@args) = @_;
269
270                   ...
271                   $self->$orig(@args);
272                   ...
273
274                   return ...;
275               });
276
277           The original sub is passed in as the first argument, even before
278           $self. You are responsible for making sure your wrapper sub returns
279           the correct thing.
280
281       $mock->autoload
282           This will inject an "AUTOLOAD" sub into the class. This autoload
283           will automatically generate read-write accessors for any sub called
284           that does not already exist.
285
286       $mock->block_load
287           This will prevent the real class from loading until the mock is
288           destroyed. This will fail if the class is already loaded. This will
289           let you mock a class completely without loading the original
290           module.
291
292       $pm_file = $mock->file
293           This returns the relative path to the file for the module. This
294           corresponds to the %INC entry.
295
296       $bool = $mock->purge_on_destroy($bool)
297           When true, this will cause the package stash to be completely
298           obliterated when the mock object falls out of scope or is otherwise
299           destroyed. You do not normally want this.
300
301       $stash = $mock->stash
302           This returns the stash for the class being mocked. This is the
303           equivalent of:
304
305               my $stash = \%{"${class}\::"};
306
307           This saves you from needing to turn off strict.
308
309       $class = $mock->class
310           The class being mocked by this instance.
311
312       $p = $mock->parent
313           If you mock a class twice the first instance is the parent, the
314           second is the child. This prevents the parent from being destroyed
315           before the child, which would lead to a very unpleasant situation.
316
317       $c = $mock->child
318           Returns the child mock, if any.
319

SOURCE

321       The source code repository for Test2-Suite can be found at
322       <https://github.com/Test-More/Test2-Suite/>.
323

MAINTAINERS

325       Chad Granum <exodist@cpan.org>
326

AUTHORS

328       Chad Granum <exodist@cpan.org>
329
331       Copyright 2018 Chad Granum <exodist@cpan.org>.
332
333       This program is free software; you can redistribute it and/or modify it
334       under the same terms as Perl itself.
335
336       See <https://dev.perl.org/licenses/>
337
338
339
340perl v5.32.0                      2020-12-16                    Test2::Mock(3)
Impressum