2016-05-10 34 views
4

我已經繼承了perl代碼庫。考慮下面的子程序;重構perl子的可測試性

sub getSysRTable 
{ 
    my $iface = shift; 
    return if not length($iface); 
    my %ip_routes; 
    my @routes = `/usr/bin/netstat -rn`; 
    foreach my $route(@routes) { 
     if ($route =~ /([\S.]+)\s+([\d.]+.[\d.]+.[\d.]+.[\d.]+)\s+(UGS|UGHS)\s+($iface)/) 
      { $ip_routes {$1} = $2 } 
    } 
    return %ip_routes; 
} 

我想寫這個代碼的單元測試。我所考慮的測試將使用netstat -rn的示例輸出並檢查預期的行爲。該子是,調用一個命令,所以注入我的測試數據是有問題的這個實現。

什麼是重構這個子可測性的慣用perlish方法?

+4

參見[如何嘲笑Perl的內置反引號操作符?(HTTP: //stackoverflow.com/q/3678655/176646) – ThisSuitIsBlackNot

+0

另外,在* nix'netstat -r'只是從/ proc/net/route中提取數據,所以你可以直接解析它。 – ThisSuitIsBlackNot

回答

5

首先,改變你的代碼如下:

sub getDataForSysRTable { 
    return `/usr/bin/netstat -rn`; 
} 

sub getSysRTable 
{ 
    my $iface = shift; 
    return if not length($iface); 
    my %ip_routes; 
    my @routes = getDataForSysRTable(); 
    foreach my $route(@routes) { 
     if ($route =~ /([\S.]+)\s+([\d.]+.[\d.]+.[\d.]+.[\d.]+)\s+(UGS|UGHS)\s+($iface)/) 
      { $ip_routes {$1} = $2 } 
    } 
    return %ip_routes; 
} 

然後將你的測試,你可以做

local *getDataForSysRTable = sub { 
    ... return known data ... 
}; 

my $ip_routes = getSysRTable($iface); 
+2

對於模擬子程序,我更喜歡使用http://search.cpan.org/~gfranks/Test-MockModule-0.11/lib/Test/MockModule.pm – bart