簡體   English   中英

在perl中存根並模擬subrotine以進行單元測試

[英]stub and mock a subrotine for unit testing in perl

我正在嘗試對該模塊進行單元測試。 我需要幫助和信息,如何模擬或添加子例程來測試程序包。

我不想使用在cpan上遇到的模塊

通過在測試中按以下方式覆蓋它們,可以創建模擬子:

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

您通常希望設置一個變量,以便稍后在模擬中的測試中進行檢查。

(即使我建議使用Test :: MockModule,但您明確指定不使用它)

很難說出您可能需要解決的條件,因為您沒有提供太多細節。 因此,這是模擬子例程中涉及的內容的一般概述。

Perl將包子例程存儲在符號表中,我們可以通過“ globs”訪問它們。 將程序包Some::Package的子例程do_the_thing分配給符號 *Some::Package::do_the_thing的最后一個子程序,它將替換該子程序的常規功能。 我們也可以檢索它,以便調用它。

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

請注意,要訪問它,我們必須告訴它訪問glob的CODE插槽。 要替換潛水艇,我們不需要。 Perl知道將代碼引用分配給glob的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];
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM