Eden CardimPublicado em 01/03/2013
Suponha, por exemplo, um cliente mínimo de API da wikipedia:
package Wikipedia::API;
use Moose;
use JSON;
use LWP::UserAgent;
has ua => (
is => 'rw',
handles => [qw(get)],
default => sub { LWP::UserAgent->new; }
);
has json => (
is => 'rw',
handles => [qw(decode)],
default => sub { JSON->new->utf8 }
);
around get => sub {
my $orig = shift;
my $self = shift;
my $res = $self->$orig(@_);
return $self->decode( $res->content );
};
sub query {
my ( $self, $page, $prop ) = @_;
my $url =
q{http://br.wikipedia.org/w/api.php?format=json&action=query}
. qq{&titles=$page}
. qq{&prop=$prop};
return $self->get($url);
}
Para testar esse código, precisamos averiguar se o conteúdo da requisição realmente contém os valores esperados:
use Test::More;
use Data::Dump;
my $expected = {
query => {
pages => {
39 => {
ns => 0,
pageid => 39,
revisions => [
{ anon => "",
comment => "",
parentid => 69,
revid => 4916,
timestamp => "2004-06-27T17:34:56Z",
user => "81.220.117.157",
},
],
title => "Main Page",
},
},
},
};
my $wapi = Wikipedia::API->new;
is_deeply( $wapi->query( 'Main Page', 'revisions' ), $expected );
done_testing();
Porém o sucesso do teste depende de uma série de fatores externos que não necessariamente envolvem a corretude do código como ter acesso ao servidor remoto que está sendo testado e depender que serviço retorne sempre os mesmos valores, nesse exato momento em que você lê isso, provavelmente o valor retornado pelo código será diferente. Além disso, numa suite de testes grande, executar requisições remotas pode ser demorado e tedioso.
Plack::Test::Agent
, que possui a mesma interface do LWP::UserAgent
porém ele simula requisições contra uma aplicação escrita usando Plack
.
O problema é resolvido com o middleware de Cache e um Proxy para o serviço original.
my $ua = Plack::Test::Agent->new(
app => builder {
enable 'Cache',
match_url => '/.*',
cache_dir => q{/tmp/api-cache};
mount '/' => Plack::App::Proxy->new(
remote => 'http://api.discogs.com',
backend => 'LWP'
)->to_app;
}
);
my $wapi = Wikipedia::API->new(ua => $ua);
Observe como "enganamos" a biblioteca para que ela passe pelo nosso proxy recém-montado, que irá responder exatamente da mesma forma que o serviço original, exceto que o middleware de cache irá armazenar cada resposta do servidor localmente, para que num segundo acesso, não seja necessário entrar em contato com o servidor de fato.
Nesse caso, as requisições ficam cacheadas num diretório temporário, mas os arquivos gerados pelo cache podem ser armazenados no repositório, junto com o código. Se houver necessidade de atualizar os dados do serviço, basta remover os arquivos de cache e corrigir os valores esperados pelo código.