How to make Fake HTTP response objects for testing in perl
I have written a perl script that feeds data into a web service.
I have some system tests for the perl script that check that I can interact with the webservice, and these work just fine, but I do not want to be running system tests when I make small changes - I want to run unit tests:
So far I have written a subclass of my importer that simply intercepts the web requests before it actua开发者_StackOverflow社区lly calls the URL in question and tests that all the inputs are of the right type and form, and this works fine in all cases except where the perl script needs to read the response for instructions, and then proceed to the next steps.
My problem is that I cannot fake a response object.
I've tried using HTTP::Response->new, but it keeps complaining about bad header arguments
How do I best FAKE a response object?
There is no need to mock the HTTP::Response object. They are easy to construct—at least as easy as mocking would be and less likely to introduce bugs into the tests. You need to read the documentation and not just guess at usage.
You can construct them in code, of course, but what I've done in the past more than once is just save the output of curl
or a stringified request that was made against an application and parse it back into an object.
Try playing around with these–
use warnings;
use strict;
use HTTP::Response;
my $response = HTTP::Response->new(204);
print $response->as_string;
my $other = HTTP::Response->parse(join "", <DATA>);
print $other->decoded_content, $/;
__DATA__
HTTP/1.1 200 OK
Cache-Control: public, max-age=53
Content-Type: text/html; charset=utf-8
Expires: Wed, 06 Jul 2011 19:13:54 GMT
Last-Modified: Wed, 06 Jul 2011 19:12:54 GMT
Vary: *
Date: Wed, 06 Jul 2011 19:12:59 GMT
Content-Length: 198121
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Stack Overflow</title>
</head>
<body class="home-page">
<blockquote>O HAI!</blockquote>
</body>
</html>
You may be looking for mock objects - in this case a mock LWP object?
See Test::Mock::LWP on CPAN.
Its documentation shows usage like this:
use Test::Mock::LWP;
# Setup fake response content and code
$Mock_response->mock( content => sub { 'foo' } );
$Mock_resp->mock( code => sub { 201 } );
# Validate args passed to request constructor
is_deeply $Mock_request->new_args, \@expected_args;
# Validate request headers
is_deeply [ $Mock_req->next_call ],
[ 'header', [ 'Accept', 'text/plain' ] ];
# Special User Agent Behaviour
$Mock_ua->mock( request => sub { die 'foo' } );
If you search CPAN for Test::Mock, there are quite a few modules for mocking/faking objects for testing.
精彩评论