title: How can I use Test::LWP::UserAgent if I cannot replace the $ua in the app code directly?
body: <p>I've got a sub that retrieves some data from an API via a REST service. The code is rather simple, but I need to post parameters to the API and I need to use SSL, so I have to go through <a href="https://metacpan.org/module/LWP%3a%3aUserAgent" rel="nofollow">LWP::UserAgent</a> and cannot use <a href="https://metacpan.org/module/LWP%3a%3aSimple" rel="nofollow">LWP::Simple</a>. This is a simplified version of it.</p>
  
  <pre><code>sub _request {
    my ( $action, $params ) = @_;
  
    # User Agent fuer Requests
    my $ua = LWP::UserAgent-&gt;new;
    $ua-&gt;ssl_opts( SSL_version =&gt; 'SSLv3' );
  
    my $res = $ua-&gt;post( 
      $url{$params-&gt;{'_live'} ? 'live' : 'test'}, { action =&gt; $action, %$params } 
    );
    if ( $res-&gt;is_success ) {
      my $json = JSON-&gt;new;
  
      return $json-&gt;decode( $res-&gt;decoded_content );
    } else {
      cluck $res-&gt;status_line;
      return;
    }
  }
  </code></pre>
  
  <p>This is the only place in my module (which is not OOp) where I need the <code>$ua</code>.</p>
  
  <p>Now I want to write a test for this and after some <a href="http://www.perladvent.org/2012/2012-12-12.html" rel="nofollow">research</a> decided it would be best to use <a href="https://metacpan.org/module/Test%3a%3aLWP%3a%3aUserAgent" rel="nofollow">Test::LWP::UserAgent</a>, which sounds really promissing. Unfortunately, there's a catch. In the doc, it says:</p>
  
  <blockquote>
    <p>Note that LWP::UserAgent itself is not monkey-patched - you must use
    this module (or a subclass) to send your request, or it cannot be
    caught and processed.</p>
    
    <p>One common mechanism to swap out the useragent implementation is via a
    lazily-built Moose attribute; if no override is provided at
    construction time, default to LWP::UserAgent->new(%options).</p>
  </blockquote>
  
  <p>Arghs. Obviously I cannot do the Moose thing. I can't just pass a <code>$ua</code> to the sub, either. I could of course add an optional third param <code>$ua</code> to the sub, but I don't like the idea of doing that. I feel it's not ok to alter the behaviour of such simple code so radically just to make it testable.</p>
  
  <p>What I basically want to do is run my test like this:</p>
  
  <pre><code>use strict;
  use warnings;
  use Test::LWP::UserAgent;
  use Test::More;
  
  require Foo;
  
  Test::LWP::UserAgent-&gt;map_response( 'www.example.com',
    HTTP::Response-&gt;new( 200, 'OK', 
      [ 'Content-Type' =&gt; 'text/plain' ], 
      '[ "Hello World" ]' ) );
  
  is_deeply(
    Foo::_request('https://www.example.com', { foo =&gt; 'bar' }),
    [ 'Hello World' ],
    'Test foo'
  );
  </code></pre>
  
  <p><strong>Is there a way to monkeypatch the Test::LWP::UserAgent functionality into LWP::UserAgent so that my code just uses the Test:: one?</strong></p>