File Coverage

blib/lib/Test/MockObject/Extra.pm
Criterion Covered Total %
statement 37 39 94.8
branch 5 10 50.0
condition n/a
subroutine 7 7 100.0
pod 2 2 100.0
total 51 58 87.9


line stmt bran cond sub pod time code
1 1     1   887 use strict;
  1         2  
  1         39  
2 1     1   6 use warnings;
  1         1  
  1         45  
3              
4             package Test::MockObject::Extra;
5              
6 1     1   20 use base 'Test::MockObject';
  1         2  
  1         954  
7              
8             =head1 NAME
9              
10             Test::MockObject::Extra - A little bit Extra on top of Test::MockObject
11              
12             =head1 SYNOPSIS
13              
14             # Create a mock
15             my $mock = Test::MockObject::Extra->new();
16              
17             # Fake out a module
18             $mock->fake_module(
19             'Some::Module',
20             som_sub => sub { ... },
21             );
22            
23             # Do some testing....
24            
25             ...
26            
27             # Remove the fake module
28             $mock->unfake_module;
29            
30             =head1 DESCRIPTION
31              
32             This module adds a bit of extra functionality I needed in Test::MockObject.
33             It could probably be rolled into Test::MockObject if the author wants it.
34              
35             Test::MockObject::Extra inherits from Test::MockObject. It overrides
36             fake_module() and adds a new method unfake_module(). These are described
37             below.
38              
39             =head1 METHODS
40            
41             =head2 C), [ I => I, ... ]
42              
43             Works in the same way as Test::MockObject, except it emits a warning if
44             called as a class method. This is because (in order for unfake_module()
45             to work) it needs to record what subs have been faked, so they can
46             be restored later.
47              
48             =cut
49              
50             sub fake_module {
51 1     1 1 445 my ($class, $modname, %subs) = @_;
52            
53 1 50       5 unless (ref $class) {
54 0         0 require Carp;
55 0         0 Carp::carp("fake_module() called as class method - calling of unfake_module() unsupported");
56             }
57              
58 1         8 $class->SUPER::fake_module($modname, %subs);
59            
60 1 50       48 if (ref $class) {
61 1         8 $class->{_faked_module_name} = $modname;
62            
63 1         3 for my $sub (keys %subs)
64             {
65 1 50       4 push @{$class->{_faked_subs}}, $sub if ref $class;
  1         6  
66             }
67             }
68             }
69              
70             =head2 C
71              
72             If you've called fake_module() (or fake_new()), you may need to 'unfake' it
73             later, so the real class can load. This is especially true if you have a whole
74             lot of tests running in one process (such as under Test::Class::Load).
75              
76             Note, that after calling unfake_module(), you'll need to load the real version
77             of the module in some way (this could probably be added as an option to this
78             method at a later date). If you're loading the modules you're testing with
79             use_ok(), you should be OK.
80              
81             Also note it's possible to call fake_module() as a class method. If you do this,
82             unfake_module() will die if you call it, since it needs
83             to hold onto some state data in order to unfake the module.
84              
85             =cut
86              
87             sub unfake_module {
88 1     1 1 384 my ($class) = @_;
89            
90 1         8 require Carp;
91 1 50       5 Carp::croak("unfake_module() can't be called as a class method") unless ref $class;
92            
93 1         3 my $modname = $class->{_faked_module_name};
94            
95 1 50       4 Carp::croak("Can't unfake module - don't know the module name. Did you call fake_module() as a class method?") unless $modname;
96            
97 1         2 $modname =~ s!::!/!g;
98 1         3 delete $INC{ $modname . '.pm' };
99            
100             {
101 1     1   3717 no strict 'refs';
  1         3  
  1         54  
  1         2  
102 1         2 delete ${ $modname . '::' }{VERSION};
  1         3  
103             }
104            
105 1     1   14 no strict 'refs';
  1         2  
  1         86  
106 1         2 foreach my $sub (@{$class->{_faked_subs}}) {
  1         2  
107 1         2 undef *{ $class->{_faked_module_name} . '::' . $sub };
  1         8  
108             }
109             }
110              
111             =head1 AUTHOR
112              
113             Sam Crawley (Mutant) - mutant dot nz at gmail dot com
114              
115             =head1 LICENSE
116              
117             You may distribute this code under the same terms as Perl itself.
118              
119             =cut
120              
121             1;