1Mock::Quick(3) User Contributed Perl Documentation Mock::Quick(3)
2
3
4
6 Mock::Quick - Quickly mock objects and classes, even temporarily
7 replace them, side-effect free.
8
10 Mock-Quick is here to solve the current problems with Mocking
11 libraries.
12
13 There are a couple Mocking libraries available on CPAN. The primary
14 problems with these libraries include verbose syntax, and most
15 importantly side-effects. Some Mocking libraries expect you to mock a
16 specific class, and will unload it then redefine it. This is
17 particularly a problem if you only want to override a class on a
18 lexical level.
19
20 Mock-Quick provides a declarative mocking interface that results in a
21 very concise, but clear syntax. There are separate facilities for
22 mocking object instances, and classes. You can quickly create an
23 instance of an object with custom attributes and methods. You can also
24 quickly create an anonymous class, optionally inheriting from another,
25 with whatever methods you desire.
26
27 Mock-Quick also provides a tool that provides an OO interface to
28 overriding methods in existing classes. This tool also allows for the
29 restoration of the original class methods. Best of all this is a
30 localized tool, when your control object falls out of scope the
31 original class is restored.
32
34 MOCKING OBJECTS
35 use Mock::Quick;
36
37 my $obj = qobj(
38 foo => 'bar', # define attribute
39 do_it => qmeth { ... }, # define method
40 ...
41 );
42
43 is( $obj->foo, 'bar' );
44 $obj->foo( 'baz' );
45 is( $obj->foo, 'baz' );
46
47 $obj->do_it();
48
49 # define the new attribute automatically
50 $obj->bar( 'xxx' );
51
52 # define a new method on the fly
53 $obj->baz( qmeth { ... });
54
55 # remove an attribute or method
56 $obj->baz( qclear() );
57
58 STRICTER MOCK
59 use Mock::Quick;
60
61 my $obj = qstrict(
62 foo => 'bar', # define attribute
63 do_it => qmeth { ... }, # define method
64 ...
65 );
66
67 is( $obj->foo, 'bar' );
68 $obj->foo( 'baz' );
69 is( $obj->foo, 'baz' );
70
71 $obj->do_it();
72
73 # remove an attribute or method
74 $obj->baz( qclear() );
75
76 You can no longer auto-vivify accessors and methods in strict mode:
77
78 # Cannot define the new attribute automatically
79 dies_ok { $obj->bar( 'xxx' ) };
80
81 # Cannot define a new method on the fly
82 dies_ok { $obj->baz( qmeth { ... }) };
83
84 In order to add methods/accessors you need to create a control object.
85
86 CONTROL OBJECTS
87 Control objects are objects that let you interface a mocked object.
88 They let you add attributes and methods, or even clear them. This is
89 unnecessary unless you use strict mocking, or choose not to import
90 qmeth() and qclear().
91
92 Take Control
93 my $control = qcontrol( $obj );
94
95 Add Attributes
96 $control->set_attributes(
97 foo => 'bar',
98 ...
99 );
100
101 Add Methods
102 $control->set_methods(
103 do_it => sub { ... }, # No need to use qmeth()
104 ...
105 );
106
107 Clear Attributes/Methods
108 $control->clear( qw/foo do_it .../ );
109
110 Toggle strict
111 $control->strict( $BOOL );
112
113 Create With Control
114 my $obj = qobj ...;
115 my $obj = qstrict ...;
116 my ( $obj, $control ) = qobjc ...;
117 my ( $sobj, $scontrol ) = qstrictc ...;
118
119 MOCKING CLASSES
120 Note: the control object returned here is of type Mock::Quick::Class,
121 whereas control objects for qobj style objects are of
122 Mock::Quick::Object::Control.
123
124 IMPLEMENT A CLASS
125
126 This will implement a class at the namespace provided via the
127 -implement argument. The class must not already be loaded. Once
128 complete the real class will be prevented from loading until you call
129 undefine() on the control object.
130
131 use Mock::Quick;
132
133 my $control = qclass(
134 -implement => 'My::Package',
135
136 # Insert a generic new() method (blessed hash)
137 -with_new => 1,
138
139 # Inheritance
140 -subclass => 'Some::Class',
141 # Can also do
142 -subclass => [ 'Class::A', 'Class::B' ],
143
144 # generic get/set attribute methods.
145 -attributes => [ qw/a b c d/ ],
146
147 # Method that simply returns a value.
148 simple => 'value',
149
150 # Custom method.
151 method => sub { ... },
152 );
153
154 my $obj = $control->package->new;
155 # OR
156 my $obj = My::Package->new;
157
158 # Override a method
159 $control->override( foo => sub { ... });
160
161 # Restore it to the original
162 $control->restore( 'foo' );
163
164 # Remove the namespace we created, which would allow the real thing to load
165 # in a require or use statement.
166 $control->undefine();
167
168 You can also use the qimplement() method instead of qclass:
169
170 use Mock::Quick;
171
172 my $control = qimplement 'Some::Package' => ( %args );
173
174 ANONYMOUS MOCKED CLASS
175
176 This is if you just need to generate a class where the package name
177 does not matter. This is done when the -takeover and -implement
178 arguments are both omitted.
179
180 use Mock::Quick;
181
182 my $control = qclass(
183 # Insert a generic new() method (blessed hash)
184 -with_new => 1,
185
186 # Inheritance
187 -subclass => 'Some::Class',
188 # Can also do
189 -subclass => [ 'Class::A', 'Class::B' ],
190
191 # generic get/set attribute methods.
192 -attributes => [ qw/a b c d/ ],
193
194 # Method that simply returns a value.
195 simple => 'value',
196
197 # Custom method.
198 method => sub { ... },
199 );
200
201 my $obj = $control->package->new;
202
203 # Override a method
204 $control->override( foo => sub { ... });
205
206 # Restore it to the original
207 $control->restore( 'foo' );
208
209 # Remove the anonymous namespace we created.
210 $control->undefine();
211
212 TAKING OVER EXISTING/LOADED CLASSES
213
214 use Mock::Quick;
215
216 my $control = qtakeover 'Some::Package' => ( %overrides );
217
218 # Override a method
219 $control->override( foo => sub { ... });
220
221 # Restore it to the original
222 $control->restore( 'foo' );
223
224 # Destroy the control object and completely restore the original class
225 # Some::Package.
226 $control = undef;
227
228 You can also do this through qclass():
229
230 use Mock::Quick;
231
232 my $control = qclass(
233 -takeover => 'Some::Package',
234 %overrides
235 );
236
238 All control objects have a 'metrics' method. The metrics method returns
239 a hash where keys are method names, and values are the number of times
240 the method has been called. When a method is altered or removed the key
241 is deleted.
242
243 Metrics only apply to mocked methods. When you takeover an already
244 loaded class metrics will only track overridden methods.
245
247 Mock-Quick uses Exporter::Declare. This allows for exports to be
248 prefixed or renamed. See "RENAMING IMPORTED ITEMS" in
249 Exporter::Declare for more information.
250
251 $obj = qobj( attribute => value, ... )
252 ( $obj, $control ) = qobjc( attribute => value, ... )
253 Create an object. Every possible attribute works fine as a get/set
254 accessor. You can define other methods using qmeth {...} and
255 assigning that to an attribute. You can clear a method using
256 qclear() as an argument.
257
258 See Mock::Quick::Object for more.
259
260 $obj = qstrict( attribute => value, ... )
261 ( $obj, $control ) = qstrictc( attribute => value, ... )
262 Create a stricter object, get/set accessors will not autovivify
263 into existence for undefined attributes.
264
265 $control = qclass( -config => ..., name => $value || sub { ... }, ... )
266 Define an anonymous package with the desired methods and
267 specifications.
268
269 See Mock::Quick::Class for more.
270
271 $control = qclass( -takeover => $package, %overrides )
272 $control = qtakeover( $package, %overrides );
273 Take over an existing class.
274
275 See Mock::Quick::Class for more.
276
277 $control = qimplement( $package, -config => ..., name => $value || sub
278 { ... }, ... )
279 $control = qclass( -implement => $package, ... )
280 Implement the given package to specifications, altering %INC so
281 that the real class will not load. Destroying the control object
282 will once again allow the original to load.
283
284 qclear()
285 Returns a special reference that when used as an argument, will
286 cause Mock::Quick::Object methods to be cleared.
287
288 qmeth { my $self = shift; ... }
289 Define a method for an Mock::Quick::Object instance.
290
291 default_export qcontrol => sub {
292 Mock::Quick::Object::Control->new( @_ ) };
293
295 Chad Granum exodist7@gmail.com
296
297 Ben Hengst notbenh@cpan.org
298
300 Contributors are listed as authors in modules they have touched.
301
302 Ben Hengst notbenh@cpan.org
303 Glen Hinkle glen@empireenterprises.com
304
306 Copyright (C) 2011 Chad Granum
307
308 Mock-Quick is free software; Standard perl licence.
309
310 Mock-Quick is distributed in the hope that it will be useful, but
311 WITHOUT ANY WARRANTY; without even the implied warranty of
312 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the license
313 for more details.
314
315
316
317perl v5.30.1 2020-01-30 Mock::Quick(3)