1Test::Stream::Mock(3) User Contributed Perl DocumentationTest::Stream::Mock(3)
2
3
4
6 Test::Stream::Mock - Module for managing mocked classes and instances.
7
9 This distribution is deprecated in favor of Test2, Test2::Suite, and
10 Test2::Workflow.
11
12 See Test::Stream::Manual::ToTest2 for a conversion guide.
13
15 This module lets you add and override methods for any package
16 temporarily. When the instance is destroyed it will restore the package
17 to its original state.
18
20 use Test::Stream::Mock;
21 use MyClass;
22
23 my $mock = Test::Stream::Mock->new(
24 class => 'MyClass',
25 override => [
26 name => sub { 'fred' },
27 ...
28 ],
29 add => [
30 is_mocked => sub { 1 }
31 ...
32 ],
33 ...
34 );
35
36 # Unmock the 'name' sub
37 $mock->restore('name');
38
39 ...
40
41 $mock = undef; # Will remove all the mocking
42
45 $mock = $class->new(class => $CLASS, ...)
46 This will create a new instance of Test::Stream::Mock that manages
47 mocking for the specified $CLASS.
48
49 Any "Test::Stream::Mock" method can be used as a constructor
50 argument, each should be followed by an arrayref of arguments to be
51 used with the method. For instance the 'add' method:
52
53 my $mock = Test::Stream::Mock->new(
54 class => 'AClass',
55 add => [foo => sub { 'foo' }],
56 );
57
58 is identical to this:
59
60 my $mock = Test::Stream::Mock->new(
61 class => 'AClass',
62 );
63 $mock->add(foo => sub { 'foo' });
64
65 $mock->add('symbol' => ..., 'synbol2' => ...)
66 $mock->override('symbol1' => ..., 'symbol2' => ...)
67 add() and override() are the primary ways to add/modify methods for
68 a class. Both accept the exact same type of arguments. The
69 difference is that "override" will fail unless the symbol you are
70 overriding already exists, "add" on the other hand will fail if the
71 symbol does already exist.
72
73 Note: Think of override as a push operation. If you call override
74 on the same symbol multiple times it will track that. You can use
75 restore() as a pop operation to go back to the previous mock.
76 "reset" can be used to remove all the mocking for a symbol.
77
78 Arguments must be a symbol name, with optional sigil, followed by a
79 new specification of the symbol. If no sigil is specified then '&'
80 (sub) is assumed. A simple example of overriding a sub:
81
82 $mock->override(foo => sub { 'overridden foo' });
83 my $val = $class->foo; # Runs our override
84 # $val is now set to 'overridden foo'
85
86 You can also simply provide a value and it will be wrapped in a sub
87 for you:
88
89 $mock->override( foo => 'foo' );
90
91 The example above will generate a sub that always returns the
92 string 'foo'.
93
94 There are 3 *special* values that can be used to generate
95 accessors:
96
97 $mock->add(
98 name => 'rw', # Generates a read/write accessor
99 age => 'ro', # Generates a read only accessor
100 size => 'wo', # Generates a write only accessor
101 );
102
103 If you want to have a sub that actually returns on of the 3 special
104 strings, or that returns a coderef, you can use a hashref as the
105 spec:
106
107 my $ref = sub { 'my sub' };
108 $mock->add(
109 rw_string => { val => 'rw' },
110 ro_string => { val => 'ro' },
111 wo_string => { val => 'wo' },
112 coderef => { val => $ref }, # the coderef method returns $ref each time
113 );
114
115 You can also override/add other symbol types, such as hash:
116
117 package Foo;
118 ...
119
120 $mock->add('%foo' => {a => 1});
121
122 print $Foo::foo{a}; # prints '1'
123
124 You can also tell mock to deduce the symbol type for the
125 add/override from the reference, rules are similar to glob
126 assignments:
127
128 $mock->add(
129 -foo => sub { 'foo' }, # Adds the &foo sub to the package
130 -foo => { foo => 1 }, # Adds the %foo hash to the package
131 -foo => [ 'f', 'o', 'o' ], # Adds the @foo array to the package
132 -foo => \"foo", # Adds the $foo scalar to the package
133 );
134
135 $mock->restore($SYMBOL)
136 Restore the symbol to what it was before the last override. If the
137 symbol was recently added this will remove it. If the symbol has
138 been overriden multiple times this will ONLY restore it to the
139 previous state. Think of override as a push operation, this is the
140 pop operation.
141
142 $mock->reset($SYMBOL)
143 Remove all mocking of the symbol, restore the original symbol. If
144 the symbol was initially added then it will be completely removed.
145
146 $mock->orig($SYMBOL)
147 This will return the original symbol, before any mocking. For
148 symbols that were added this will return undef.
149
150 $mock->current($SYMBOL)
151 This will return the current symbol.
152
153 $mock->reset_all
154 Remove all added symbols, and restore all overriden symbols to
155 their originals.
156
157 $mock->add_constructor($NAME => $TYPE)
158 $mock->override_constructor($NAME => $TYPE)
159 This can be used to inject constructors. The first argument should
160 be the name of the constructor. The second argument specifies the
161 constructor type.
162
163 The "hash" type is the most common, all arguments are used to
164 create a new hash that is blessed.
165
166 hash => sub {
167 my ($class, %params) = @_;
168 return bless \%params, $class;
169 };
170
171 The "array" type is similar to the hash type, but accepts a list
172 instead of key/value pairs:
173
174 array => sub {
175 my ($class, @params) = @_;
176 return bless \@params, $class;
177 };
178
179 The "ref" type takes a reference and blesses it. This will modify
180 your original input argument.
181
182 ref => sub {
183 my ($class, $params) = @_;
184 return bless $params, $class;
185 };
186
187 The "ref_copy" type will copy your reference and bless the copy:
188
189 ref_copy => sub {
190 my ($class, $params) = @_;
191 my $type = reftype($params);
192
193 return bless {%$params}, $class
194 if $type eq 'HASH';
195
196 return bless [@$params], $class
197 if $type eq 'ARRAY';
198
199 croak "Not sure how to construct an '$class' from '$params'";
200 };
201
202 $mock->before($NAME, sub { ... })
203 This will replace the orignal sub $NAME with a new sub that calls
204 your custom code just before calling the original method. The
205 return from your custom sub is ignored. Your sub and the original
206 both get the unmodified arguments.
207
208 $mock->after($NAME, sub { ... })
209 This is similar to before, except your callback runs after the
210 original code. The return from your callback is ignored.
211
212 $mock->around($NAME, sub { ... })
213 This gives you the chance to wrap the original sub:
214
215 $mock->around(foo => sub {
216 my $orig = shift;
217 my $self = shift;
218 my (@args) = @_;
219
220 ...
221 $orig->(@args);
222 ...
223
224 return ...;
225 });
226
227 The original sub is passed in as the first argument, even before
228 $self. You are responsible for making sure your wrapper sub returns
229 the correct thing.
230
231 $mock->autoload
232 This will inject an "AUTOLOAD" sub into the class. This autoload
233 will automatically generate read-write accessors for any sub called
234 that does not already exist.
235
236 $mock->block_load
237 This will prevent the real class from loading until the mock is
238 destroyed. This will fail if the class is already loaded. This will
239 let you mock a class completely without loading the original
240 module.
241
242 $pm_file = $mock->file
243 This returns the relative path to the file for the module. This
244 corresponds to the %INC entry.
245
246 $bool = $mock->purge_on_destroy($bool)
247 When true, this will cause the package stash to be completely
248 obliterated when the mock object falls out of scope or is otherwise
249 destroyed. You do not normally want this.
250
251 $stash = $mock->stash
252 This returns the stash for the class being mocked. This is the
253 equivelent of:
254
255 my $stash = \%{"${class}\::"};
256
257 This saves you from needing to turn off strict.
258
259 $class = $mock->class
260 The class being mocked by this instance.
261
262 $p = $mock->parent
263 If you mock a class twice the first instance is the parent, the
264 second is the child. This prevents the parent from being destroyed
265 before the child, which would lead to a very unpleasant situation.
266
267 $c = $mock->child
268 Returns the child mock, if any.
269
271 The source code repository for Test::Stream can be found at
272 http://github.com/Test-More/Test-Stream/.
273
275 Chad Granum <exodist@cpan.org>
276
278 Chad Granum <exodist@cpan.org>
279
281 Copyright 2015 Chad Granum <exodist7@gmail.com>.
282
283 This program is free software; you can redistribute it and/or modify it
284 under the same terms as Perl itself.
285
286 See http://dev.perl.org/licenses/
287
288
289
290perl v5.36.0 2023-01-20 Test::Stream::Mock(3)