【发布时间】:2013-02-19 14:55:44
【问题描述】:
我有一个 sub 通过 REST 服务从 API 检索一些数据。代码比较简单,但是我需要将参数post到API中,并且需要使用SSL,所以必须通过LWP::UserAgent,不能使用LWP::Simple。这是它的简化版本。
sub _request {
my ( $action, $params ) = @_;
# User Agent fuer Requests
my $ua = LWP::UserAgent->new;
$ua->ssl_opts( SSL_version => 'SSLv3' );
my $res = $ua->post(
$url{$params->{'_live'} ? 'live' : 'test'}, { action => $action, %$params }
);
if ( $res->is_success ) {
my $json = JSON->new;
return $json->decode( $res->decoded_content );
} else {
cluck $res->status_line;
return;
}
}
这是我的模块(不是 OOp)中唯一需要$ua 的地方。
现在我想为此编写一个测试,经过一些research 决定最好使用Test::LWP::UserAgent,这听起来很有希望。不幸的是,有一个问题。在文档中,它说:
请注意,LWP::UserAgent 本身没有猴子补丁 - 您必须使用 这个模块(或子类)来发送你的请求,或者它不能 捕获并处理。
换出用户代理实现的一种常见机制是通过 懒惰构建的 Moose 属性;如果没有提供覆盖 构建时间,默认为 LWP::UserAgent->new(%options)。
哎呀。显然我不能做 Moose 的事情。我也不能只将$ua 传递给潜艇。我当然可以为子添加一个可选的第三个参数$ua,但我不喜欢这样做的想法。我觉得为了使其可测试而如此彻底地改变这种简单代码的行为是不合适的。
我基本上想做的是像这样运行我的测试:
use strict;
use warnings;
use Test::LWP::UserAgent;
use Test::More;
require Foo;
Test::LWP::UserAgent->map_response( 'www.example.com',
HTTP::Response->new( 200, 'OK',
[ 'Content-Type' => 'text/plain' ],
'[ "Hello World" ]' ) );
is_deeply(
Foo::_request('https://www.example.com', { foo => 'bar' }),
[ 'Hello World' ],
'Test foo'
);
有没有办法将 Test::LWP::UserAgent 功能猴子补丁到 LWP::UserAgent 中,以便我的代码只使用 Test:: one?
【问题讨论】:
-
IMO,可测试性是一个有效的代码问题。编码的目标是拥有“有效”的东西。因此,目标状态的声明将如下所示:“它有效”。然而,经验告诉我:“在测试表明有效之前,没有任何东西‘有效’。”
标签: perl unit-testing lwp