В богатом русском языке к сожалению нет некоторых слов, поэтому вместо того чтобы начать заметку словами «Пися/Пиша модульные тесты», я вынужден удлинить фразу.
В процессе написания модульных тестов часто приходится заглядывать в старые тесты, чтобы быстро вспомнить как подменить тот или иной объект, поэтому я решил что пришло время набросать небольшую шпаргалку, авось и кому-то ещё сгодится.
Сразу прошу сильно не пинать, это шпаргалка, а не руководство, поэтому всё предельно кратко.
CPAN: Test::MockTime
CPAN: Test::Mock::Redis
insert:
для select нужно подсунуть фальшивые результаты:
Хотя так нужно тестить только модули работающие непосредственно с БД, в остальных случаях лучше подменять модули ORM или того что её заменяет ибо тесты эти сильно привязаны к реализации модуля, а лучше привязываться только к API.
CPAN: DBD::Mock
Задавая значение переменной $response управляем ответом «скрипта». Если используем content() и хотим проверить верно ли сформировался запрос, то делаем так:
Можем проверить что в $got_request именно то что мы хотели отправить
CPAN: Test::Mock::LWP
В @txt_stat можем что-то менять для разных тестов
CPAN: Test::MockObject
Подмена метода debug():
Если тесты проходят нормально, то diag shift; можно убирать чтобы не засорять вывод (завалятся так можно вернуть), аналогично можно и остальные методы подmockить
О Test::MockObject
О DBD::Mock
Ссылки подсказал mrrico
В процессе написания модульных тестов часто приходится заглядывать в старые тесты, чтобы быстро вспомнить как подменить тот или иной объект, поэтому я решил что пришло время набросать небольшую шпаргалку, авось и кому-то ещё сгодится.
Сразу прошу сильно не пинать, это шпаргалка, а не руководство, поэтому всё предельно кратко.
Подмена генератора случайных чисел
BEGIN { *CORE::GLOBAL::rand = sub {66}; }
Подмена времени
use Test::MockTime qw( :all ); set_fixed_time( 1305636470 ); # do something restore_time();
CPAN: Test::MockTime
Подмена Redis
use Test::Mock::Redis; my $redis = Test::Mock::Redis->new( server => 'whatever' );
CPAN: Test::Mock::Redis
Подмена СУБД
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
Подмена обращения к HTTP скрипту (LWP::UserAgent)
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
Подмена произвольного объекта
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
Подмена Log4perl
Подмена метода 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
О DBD::Mock
Ссылки подсказал mrrico
