package Test::MockHTTP; use warnings; use strict; =head1 NAME Test::MockHTTP - utility to test LWP usage without actual HTTP requests =cut use base qw/Exporter/; our @EXPORT = qw/http_cmp http_test_setup/; use Test::MockObject::Extends; use Test::Deep; use LWP::UserAgent; my $Http_test_setup; my $Mock_ua; =head1 SYNOPSIS use Test::MockHTTP; my $ua; http_test_setup { $ua = $_[0] }; http_cmp( sub { $ua->do_some_http_request() }, [ as_string => re('image1_link=\S+mail\.rambler\.ru'), # these are pairs of method => test againt its return # value ] ); ... =cut =head1 FUNCTIONS =head2 http_test_setup This function takes one coderef argument which gets called with a specially crafted (with mocked methods) LWP::UserAgent instance before each test. All actions should use this UA to be tested. =cut sub http_test_setup(&) { $Http_test_setup = shift; } =head2 http_cmp This is a wrapper around Test::Deep::cmp_deeply which does the actual tests. It takes 4 arguments. =over 2 =item $code This is the code to test. It gets called. =item $methods This is an arrayref of pairs 'method' => 'test against its return value'. It gets passed into Test::Deep::methods to construct a test against HTTP::Request which is provided by LWP. =item $msg TAP message, is directly passed to Test::Deep::cmp_deeply. =item $resp HTTP::Response instance which is returned as a fake response to HTTP::Request from simple_request() method. Defaults to simple '200 Ok' empty response. =back =cut sub http_cmp { my ($code, $methods, $msg, $resp) = @_; $Http_test_setup->($Mock_ua) if $Http_test_setup; $Mock_ua->mock(simple_request => sub { cmp_deeply($_[1], methods(@$methods), $msg); return $resp || HTTP::Response->new(200, 'Ok', [Server => 'mock'], '{"result": "ok"}'); # JSON }); $code->(); } $Mock_ua = Test::MockObject::Extends->new(LWP::UserAgent->new);