File Coverage

blib/lib/Test/Mock/Mango.pm
Criterion Covered Total %
statement 29 29 100.0
branch n/a
condition n/a
subroutine 11 11 100.0
pod n/a
total 40 40 100.0


line stmt bran cond sub pod time code
1             package Test::Mock::Mango;
2              
3 19     19   6503061 use v5.10;
  19         89  
  19         949  
4 19     19   121 use strict;
  19         41  
  19         671  
5 19     19   107 use warnings;
  19         41  
  19         1000  
6              
7             our $VERSION = '0.09';
8              
9             require 'Mango.pm'; # Bit useless if you don't actually have mango
10 19     19   17256 use Test::Mock::Mango::FakeData;
  19         45  
  19         557  
11 19     19   11082 use Test::Mock::Mango::DB;
  19         56  
  19         608  
12 19     19   130 use Test::Mock::Mango::Collection;
  19         35  
  19         976  
13              
14             $Test::Mock::Mango::data = Test::Mock::Mango::FakeData->new;
15             $Test::Mock::Mango::error = undef;
16             $Test::Mock::Mango::n = undef;
17              
18              
19             # Stub "Mango" itself to deal with the situations where it'll get
20             # a duff or unset connection string (if for example the context in
21             # which the code will run requires a config file but the unit test
22             # will run where this file doesn't exist).
23             {
24 19     19   97 no warnings 'redefine';
  19         32  
  19         1832  
25 16     16   6502 *Mango::new = sub { bless {}, 'Mango' };
26             }
27              
28             # If we're running with Test::Spec and in appropriate context
29             # then use Test::Spec::Mocks to do our monkey patching.
30             if (exists $INC{'Test/Spec.pm'} && Test::Spec->current_context) {
31 19     19   100 use warnings 'redefine';
  19         36  
  19         1513  
32             Mango->expects('db')->returns( Test::Mock::Mango::DB->new($_[-1]) );
33             }
34             else {
35 19     19   90 no warnings 'redefine';
  19         32  
  19         2218  
36 48     48   83012 *Mango::db = sub{Test::Mock::Mango::DB->new($_[-1])};
37             }
38              
39              
40              
41             1;
42              
43             =encoding utf8
44              
45             =head1 NAME
46              
47             Test::Mock::Mango - Simple stubbing for Mango to allow unit tests for code that uses it
48              
49             =for html
50            
51              
52             =head1 SYNOPSIS
53              
54             # Using Test::More
55             #
56             use Test::More;
57             use Test::Mock::Mango; # Stubs in effect!
58             # ...
59             done_testing();
60              
61              
62             # Using Test::Spec (uses Test::Spec::Mocks)
63             #
64             use Test::Spec;
65              
66             describe "Whilst stubbing Mango" => {
67             require Test::Mock::Mango; # Stubs in effect in scope!
68             # ...
69             };
70             runtests unless caller;
71              
72              
73             =head1 DESCRIPTION
74              
75             For L version 0.30 and higher
76              
77             L provides simple stubbing of methods in the L library
78             to allow easier unit testing of L based code.
79              
80             It does not attempt to 100% replicate the functionality of L, but instead
81             aims to provide "just enough" where sensible for the majority of use cases.
82              
83             The stubbed methods ignore actual queries being entered and
84             simply return a user-defined I. To run a test you need to set
85             up the data you expect back first - this module doesn't test your queries, it allows
86             you to test around L calls with known conditions.
87              
88              
89             =head1 STUBBED METHODS
90              
91             The following methods are available on each faked part of the mango. We
92             describe here briefly how far each actually simulates the real method.
93              
94             Each method supports blocking and non-blocking syntax if the original
95             method does. Non-blocking ops are not actually non blocking but simply
96             execute your callback straight away as there's nothing to actually go off
97             and do on an event loop.
98              
99             All methods by default simuluate execution without errors. If you want to run a test
100             that needs to respond to an error state you can do so by L.
101              
102              
103             =head2 Collection
104              
105             L
106              
107             =over 9
108              
109             =item aggregate
110              
111             Ignores query. Returns current collection documents to simulate an
112             aggregated result.
113              
114             =item create
115              
116             Doesn't really do anything.
117              
118             =item drop
119              
120             Doesn't really do anything.
121              
122             =item find_one
123              
124             Ignores query. Returns the first document from the current fake collection
125             given in L. Returns undef if the collection
126             is empty.
127              
128             =item find_and_modify
129              
130             Ignores query. Returns the first document from the current fake collection
131             given in L. Returns undef if the collection
132             is empty.
133              
134             =item find
135              
136             Ignores query. Returns a new L instance.
137              
138             =item full_name
139              
140             Returns full name of the fake collection.
141              
142             =item insert
143              
144             Naively inserts the given doc(s) onto the end of the current fake collection.
145              
146             Returns an C for each inserted document. If an C<_id> is specifiec
147             in the inserted doc then it is returned, otherwise a new
148             L is returned instead.
149              
150             =item update
151              
152             Doesn't perform a real update. You should set the data state in
153             C<$Test::Mock::Mango::data> before making the call to be what
154             you expect after the update.
155              
156             =item remove
157              
158             Doesn't remove anything.
159              
160             =back
161              
162              
163             =head2 Cursor
164              
165             L
166              
167             =over 6
168              
169             =item all
170              
171             Return array ref containing all the documents in the current fake collection.
172              
173             =item next
174              
175             Simulates a cursor by (beginning at zero) iterating through each document
176             on successive calls. Won't reset itself. If you want to reset the
177             cursor then set Cindex> to zero.
178              
179             =item count
180              
181             Returns the number of documents in the current fake collection.
182              
183             =item backlog
184              
185             Arbitarily returns 'C<2>'
186              
187             =item limit
188              
189             Passthru
190              
191             =item sort
192              
193             Passthru
194              
195             =back
196              
197              
198             =head1 TESTING ERROR STATES
199              
200             L gives you the ability to simulate errors from your
201             mango calls.
202              
203             Simply set the C var before the call:
204              
205             $Test::Mock::Mango::error = 'oh noes!';
206              
207             The next call will then run in an error state as if a real error has occurred.
208             The C var is automatically cleared with the call so you don't need
209             to C it afterwards.
210              
211              
212             =head1 TESTING UPDATE/REMOVE FAILURES ETC
213              
214             By default, L is optimistic and assumes that any operation
215             you perform has succeeded.
216              
217             However, there are times when you want to do things in the event of a
218             failure (e.g. when you attempt to update and the doc to update doesn't exist
219             - this differs from L in that nothing
220             is wrong with the call, and technically the operation has "succeeded" [mongodb
221             is funny like that ;) ])
222              
223             Mongodb normally reports this by a magic parameter called C that it passes
224             back in the resultant doc. This is set to the number of documents that have
225             been affected (e.g. if you remove two docs, it'll be set to 2, if you update
226             4 docs successfully it'll be set to 4).
227              
228             In it's optimistic simulation, L automaticaly sets the
229             C value in return docs to 1. If your software cares about the C value
230             and you want it set specifically (especially if you want to simulate say a "not
231             updated" case) you can do this via the C value of $Test::Mock::MangoL
232              
233             $Test::Mock::Mango::n = 0; # The next call will now pretend no docs were updated
234              
235             In the same way as using C<$Test::Mock::Mango::error>, this value will be
236             automatically cleared after the next call. If you want to reset it yourself
237             at any point then set it to C.
238              
239             B
240              
241             my $doc = $mango->db('family')->collection('simpsons')->update(
242             { name => 'Bart' },
243             { name => 'Bartholomew' }
244             );
245             # $doc->{n} will be 1
246              
247             $Test::Mock::Mango::n = 0;
248             my $doc = $mango->db('family')->collection('simpsons')->update(
249             { name => 'Bart' },
250             { name => 'Bartholomew' }
251             );
252             # $doc->{n} will be 0
253              
254              
255             =head1 AUTHOR
256              
257             J Gregory
258              
259             =head1 SEE ALSO
260              
261             L
262              
263             =cut