此子例程将通过对其应用正则表达式从环境中获取API主机名。
Parameters :
environment (mandatory) - http://m5devacoe01.gcsc.att.com:8174/
Returns :
host : m5devacoe01.gcsc.att.com:28174
########################################################
# Subroutine: _get_api_host_from_environment
#
# Fetches the api host name from environment by applying regex on it
#
# Parameters :
# environment (mandatory) - http://m5devacoe01.gcsc.att.com:8174/
#
# Returns :
# host : m5devacoe01.gcsc.att.com:28174
#####################################################
sub _get_api_host_from_environment {
my ($self, %args) = @_;
$self->missing_params(\%args, qw! environment!)
and return;
$args{environment} =~ /([^:\/]+):?([^\/]*)/; # http://m5devacoe01.gcsc.att.com:8174/
my $host = $1; # m5devacoe01.gcsc.att.com
my $port = $2; # 8174
# If port is provided it means that it's a development server request. So, append 2 in the port
if ($port) {
$host .= ':2' . $port;
} else {
$host .= ':4040';
}
return $host;
}
如何对此方法进行单元测试?
答案 0 :(得分:3)
您的代码实际上并不复杂。您实际上并未访问任何非常具体的内容。这只是一个参数哈希。正确的做法是测试这些情况:
这些测试都非常简单。
use Test::More;
use strict;
use warnings;
my $foo = Foo->new;
is( $foo->_get_api_host_from_environment(),
undef, 'return undef without arguments' );
is( $foo->_get_api_host_from_environment( foo => 123 ),
undef, 'return undef with missing environment' );
{
local $TODO = 'this check is not implemented yet';
is(
$foo->_get_api_host_from_environment(
environment => 'this is not a URL'
),
undef,
'environment is not a URL'
);
}
is(
$foo->_get_api_host_from_environment(
environment => 'http://example.org:8174/'
),
'example.org:28174',
'port number and trailing slash prefixes 2 to the port'
);
is(
$foo->_get_api_host_from_environment(
environment => 'http://example.org:8174'
),
'example.org:28174',
'port number w/o trailing slash prefixes 2 to the port'
);
is(
$foo->_get_api_host_from_environment(
environment => 'http://example.org/'
),
'example.org:4040',
'no port number and trailing slash adds port 4040'
);
is(
$foo->_get_api_host_from_environment(
environment => 'http://example.org'
),
'example.org:4040',
'no port number w/o trailing slash adds port 4040'
);
done_testing;
请注意我的测试如何都有描述性名称。好的测试可以作为未来维护代码的开发人员的文档(可能是一年中的代码),因此请确保您实际谈论了在描述中测试的内容和原因。
其中有$TODO
表示尚未构建对错误网址的检查。该测试将失败,但测试套件无论如何都会通过,因为预计会失败。
为了让这些测试通过,我需要在你的sub周围添加一些代码。这就是我所做的。
package Foo;
use strict;
use warnings;
sub new { return bless {}, $_[0] }
sub missing_params {
my $self = shift;
my $args = shift;
foreach my $param (@_) {
return 1 unless exists $args->{$param};
}
return;
}
sub _get_api_host_from_environment {
my ( $self, %args ) = @_;
$self->missing_params( \%args, qw! environment! )
and return;
$args{environment} =~ m{(?:https?://)?([^:\/]+):?([^\/]*)}
; # http://m5devacoe01.gcsc.att.com:8174/
my $host = $1; # m5devacoe01.gcsc.att.com
my $port = $2; # 8174
# If port is provided it means that it's a development server request. So, append 2 in the port
if ($port) {
$host .= ':2' . $port;
}
else {
$host .= ':4040';
}
return $host;
}
您会注意到我是如何更改正则表达式的。那是因为你的实际上是错的,没有做你的文档所说的代码。新模式引入了https
而不是http
作为方案的选项,我没有进行测试,也没有完整的方案。我没有包含这些案例的测试,但它们也应该存在。
实际使用URI模块可能更为明智。它允许您直接修改端口,并为您提供免费的健全性检查。
sub _get_api_host_from_environment {
my ( $self, %args ) = @_;
$self->missing_params( \%args, qw! environment! )
and return;
my $uri = URI->new( $args{environment} ) or return;
return unless $uri->scheme && $uri->scheme =~ 'http'; # includes https
my $port = $uri->port; # 8174
# If port is provided it means that it's a development server request. So, append 2 in the port
if ($port != 80 and $port != 443) {
$uri->port( '2' . $port );
}
else {
$uri->port('4040');
}
# return $uri->canonical; # this would return http://example.org:28174/
return $uri->host_port;
}
通过此测试,相同的单元测试仍将通过。