2014-02-13 4 views
0

Я пытаюсь выполнить модульное тестирование модуля. Мне нужна помощь и информация, как насмехаться или заглушить подпрограмму для тестирования пакета.заглушка и mock subrotine для модульного тестирования в perl

Я не хочу использовать модуль я наткнулся на cpan.

ответ

4

Вам макет Subs путем переопределения их следующим образом в тесте:

no warnings; 
local *Foo::bar = sub { 
    # do stuff 
}; 
use warnings; 

обычно требуется установить переменную который будет проверен позже в вашем тесте внутри вашего макета.

(даже если я предлагаю использовать Test :: MockModule, но явно указано не использовать)

2

Трудно сказать, какие условия вы, возможно, придется работать вокруг, потому что вы не даете много деталей. Итак, это общий обзор того, что связано с насмешками подпрограмм.

Perl хранит подпрограммы пакета в таблице символов, с которой мы можем получить доступ через "globs". Возьмите подпрограмму do_the_thing в пакете Some::Package, последнюю подпрограмму, которую вы назначаете на символ .*Some::Package::do_the_thing заменит нормальную функциональность этого юнита. Мы также можем получить его, чтобы мы могли позвонить ему.

my $do_the_original_thing = *Some::Package::do_the_thing{CODE}; 

Обратите внимание, что для доступа к нему, мы должны сказать ему, чтобы получить доступ к CODE слот в Glob. Чтобы заменить суб, мы этого не сделаем. Perl знает, как назначить код ref для слота CODE глобуса.

*Some::Package::do_the_thing = sub { 
    if ($_[0] eq '-reallyreallydoit' and $_[1]) { 
     shift; shift; 
     goto &$do_the_original_thing; # this does not return here 
    } 
    # do the mock thing 
    ... 
}; 

Примечание: Путь показан демонстрирует минимальный способ вызова процедуры, так он действует так же, как процедуры вы насмешливый. Если вам не нравится goto, то это делает то же самое:

 #goto &$do_the_original_thing; # this does not return here 
     return &$do_the_original_thing; # this returns here...to return 

Однако, если вы хотите проверить, что было возвращено, или сохранить его для создания будущих тестов, вы могли бы просто сделать это следующим образом:

my $future_test_value ; 
*Some::Package::do_the_thing = sub { 
    if ($_[0] eq '-reallyreallydoit' and $_[1]) { 
     shift; shift; 
     my @res; 
     if (wantarray) { 
      @res = &$do_the_original_thing; 
     } 
     elsif (!(wantarray // 1)) { 
      $res[0] = &$do_the_original_thing; 
     } 
     $future_test_value = $res[0]; 
     return wantarray ? @res : $res[0]; 
    } 
+0

Это на самом деле хорошо. Но есть ли способ использовать это без инструкции goto? – ganezdragon

+1

@ganezdragon см. Правки. – Axeman