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....

1 Comment

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! :)

Leave a comment

About Samuel Kaufman

user-pic CTO / Codemonkey, Socialflow.com