Moose MonkeyPatching With a Mock UserAgent
In this post: https://blogs.perl.org/users/samuel_kaufman/2014/06/when-a-fat-comma-is-confusing.html I mentioned I was using Test::LWP::UserAgent for my test.
One thing I struggled with was testing ( with a mockup ) a service which was being instantiated completely beyond the scope of the test- so even though it took ua
as a parameter to the constructor to override the default LWP::UserAgent->new
, I couldn't reach down inside the Catalyst controller where it instantiated a module with the default parameters from the test.
So in case anyone else has had similar issues, here's how I got it working:
use Test::LWP::UserAgent;
use HTTP::Message::PSGI;
use Moose::Util qw[ find_meta ];
my $ua = Test::LWP::UserAgent->new(cookie_jar => {} );
my $meta = find_meta('SocialFlow::LinkShortening');
$meta->make_mutable;
$meta->add_around_method_modifier( ua => sub { $ua } );
$meta->make_immutable;
$ua->register_psgi( 'socialflow',$script->psgi_app);
It's not pretty, and I can think of plenty of reasons why this is a bad idea, but it works!
Looking at it now I could've probably made 'ua' lazy_build and put an around modifier to hijack _build_ua
but that's also breaking encapsulation....
Nice! I've definitely used method modifiers (either directly in in Moose, if it's a Moose class, or otherwise using Class::Method::Modifiers) for targeted mocking - it feels a bit ugly, but it does do the job! :)