- PVSM.RU - https://www.pvsm.ru -
В богатом русском языке к сожалению нет некоторых слов, поэтому вместо того чтобы начать заметку словами «Пися/Пиша модульные тесты», я вынужден удлинить фразу.
В процессе написания модульных тестов часто приходится заглядывать в старые тесты, чтобы быстро вспомнить как подменить тот или иной объект, поэтому я решил что пришло время набросать небольшую шпаргалку, авось и кому-то ещё сгодится.
Сразу прошу сильно не пинать, это шпаргалка, а не руководство, поэтому всё предельно кратко.
BEGIN {
*CORE::GLOBAL::rand = sub {66};
}
use Test::MockTime qw( :all );
set_fixed_time( 1305636470 );
# do something
restore_time();
CPAN: Test::MockTime [1]
use Test::Mock::Redis;
my $redis = Test::Mock::Redis->new( server => 'whatever' );
CPAN: Test::Mock::Redis [2]
insert:
use DBI;
my $dbh = DBI->connect( 'dbi:Mock:', '', '' );
my $history = $dbh->{mock_all_history};
my $st = $history->[0];
# do that execute sql query
# check
is( $st->statement, $expected_sql, 'Query must be correct' );
is( $st->bound_params()->[0], 123456, 'Bound parameter must be correct' );
для select нужно подсунуть фальшивые результаты:
$dbh->{mock_add_resultset} = {
sql => 'SELECT emergency_dequeue_start()',
results => [
[ 'emergency_dequeue_start' ],
[ '11' ],
],
};
Хотя так нужно тестить только модули работающие непосредственно с БД, в остальных случаях лучше подменять модули ORM или того что её заменяет ибо тесты эти сильно привязаны к реализации модуля, а лучше привязываться только к API.
CPAN: DBD::Mock [3]
use Test::Mock::LWP;
$Mock_ua->mock( agent => sub {'My Agent 007'} );
$Mock_request->mock( content_type => sub {'application/x-www-form-urlencoded'} );
$Mock_response->mock( code => sub {200} );
$Mock_response->mock( content => sub {$response} );
$Mock_response->mock( is_error => sub {0} );
$Mock_response->mock( status_line => sub {'status line'} );
Задавая значение переменной $response управляем ответом «скрипта». Если используем content() и хотим проверить верно ли сформировался запрос, то делаем так:
$Mock_ua->mock( agent => sub { 'SMSOnline plc' } );
$Mock_request->mock( content_type => sub { 'application/x-www-form-urlencoded' } );
$Mock_request->mock( content => sub { ( my $self, $got_request ) = @_; $got_request; } );
$Mock_response->mock( code => sub { 200 } );
$Mock_response->mock( content => sub { $response } );
$Mock_response->mock( is_error => sub { 0 } );
$Mock_response->mock( status_line => sub { 'status line' } );
Можем проверить что в $got_request именно то что мы хотели отправить
CPAN: Test::Mock::LWP [4]
my $mock = Test::MockObject->new();
Test::MockObject->fake_new( 'My::Module' );
my @txt_stat = (0, 0);
$mock->mock( 'read_txt', sub { return @txt_stat; } );
$mock->mock( 'write_txt', sub { 1; } );
В @txt_stat можем что-то менять для разных тестов
CPAN: Test::MockObject [5]
Подмена метода debug():
my $logger = Test::MockObject->new();
Test::MockObject->fake_new( 'Log::Log4perl::init' );
$logger->mock( 'debug', sub { shift; diag shift; } );
Если тесты проходят нормально, то diag shift; можно убирать чтобы не засорять вывод (завалятся так можно вернуть), аналогично можно и остальные методы подmockить
О Test::MockObject [6]
О DBD::Mock [7]
Ссылки подсказал mrrico [8]
Автор: worldmind
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/perl/6091
Ссылки в тексте:
[1] Test::MockTime: http://search.cpan.org/perldoc?Test::MockTime
[2] Test::Mock::Redis: http://search.cpan.org/perldoc?Test::Mock::Redis
[3] DBD::Mock: http://search.cpan.org/perldoc?DBD::Mock
[4] Test::Mock::LWP: http://search.cpan.org/perldoc?Test::Mock::LWP
[5] Test::MockObject: http://search.cpan.org/perldoc?Test::MockObject
[6] О Test::MockObject: http://blog.openquality.ru/perl-oop-stubs/
[7] О DBD::Mock: http://www.bredoit.ru/ModulnoetestirovaniePerlskriptov.html
[8] mrrico: http://mrrico.livejournal.com/3782.html
Нажмите здесь для печати.