Ваш код на самом деле не очень сложный. Вы на самом деле не получаете ничего особенного. Это просто хэш аргументов. Что нужно сделать, это проверить эти случаи:
- называется без аргументов
- вызвано с неправильными аргументами
- вызывается со значением, которое не соответствует шаблону (потерпит неудачу, вы не учитываете это)
- вызывается с URL с косой чертой с портом
- вызывается с URL без косой черты с портом
- вызывается с URL с косой чертой без порта
- вызывается с URL без косой черты без порта
Все эти тесты довольно просты.
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
, чтобы показать, что проверка на неправильный URL еще не была построена. Этот тест не пройден, но набор тестов в любом случае пройдет, потому что ожидается его неудача.
Для того, чтобы эти тесты прошли успешно, мне нужно было добавить немного кода к вашему сабвуферу. Это то, что я сделал.
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;
}
В этом тесте все те же модульные тесты будут проходить.