Hi, are you seeking to test the processing of data received from the API? It sounds like that, by "don't wish to impose a whole bunch of HTTP requests every time tests are run." If so, I would think that you would want to leave your caching layer alone (presumably it defaults to the File CHI driver) so that it can be exercised fully. All you would want to mock in that case would be the HTTP requests themselves.
At ($job - 1) we used a customized version of Test::LWP::Recorder for this. You run your tests once with live calls, recording the entire HTTP conversation, and thereafter run them using the recorded data to mock the calls. It was quite useful, but of course involved making and recording the calls as part of updating the test suite.
At $job we handle it differently, overriding LWP::UserAgent methods to inject an HTTP::Response object created from known static data. This approach allows the code to be exercised all the way up to actually sending the request, and then all the way from when LWP receives the response. In fact I hack LWP::UserAgent::send_request to print a notice any time it actually runs (ie makes a live call), to reveal any leaks. We have a test helper class that contains the code to generate the override subs needed, since often a call to our API results in more than one call out to the provider, and you'll need a routine that hands back a sequence of mocked responses. The static data representing the mocked responses can be in the helper class or in the given test file itself. At its core the code is something like this:
local *LWP::UserAgent::get = sub { HTTP::Response->new(200, undef, und
+ef, $response_data) };
... and in our test files we are calling it something like this:
my $test = $helper->run_test({ # wraps methods get_ok, post_ok etc f
+rom Test::Mojo
uri => $some_endpoint, # what we are testing
status => 201, # expected status of call to our API
method => 'post', # HTTP method of the request
data => $json_args, # what the user would pass in the cal
+l to our API
override => [{
method => 'get', # HTTP method of the first mocked ext
+ernal call
status => 200, # mocked return status of the first m
+ocked call
content => $some_data, # mocked response content from the fi
+rst mocked call
}, {
method => 'post', # HTTP method of the second mocked ex
+ternal call
status => 201, # mocked return status of the second
+mocked call
content => $other_data, # mocked response content from the se
+cond mocked call
}],
});
$test->json_is('/result/foo', 'bar'); # Test::Mojo methods used to tes
+t the response
Hope this helps!
The way forward always starts with a minimal test.
|