2016-05-10 17 views
4

Ich habe eine Perl-Code-Basis geerbt. Betrachten Sie die folgende Subroutine;Refactor Perl Sub für Testbarkeit

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; 
} 

Ich möchte Komponententests für diesen Code schreiben. Die Tests, die ich vorhabe, werden eine Beispielausgabe von netstat -rn verwenden und auf das erwartete Verhalten prüfen. Das Sub, wie es ist, ruft einen Befehl auf, so dass das Injizieren meiner Testdaten bei dieser Implementierung problematisch ist.

Was ist der idiomatische Perish-Ansatz zum Refactoring dieses Sub zur Testbarkeit?

+4

See tun [Wie verspotten ich Perl-internen Backtick Operator?] (Http: //stackoverflow.com/q/3678655/176646) – ThisSuitIsBlackNot

+0

Außerdem zieht on * nix 'netstat -r' nur Daten aus/proc/net/route, sodass Sie sie direkt analysieren können. – ThisSuitIsBlackNot

Antwort

5

Zuerst Ihren Code wie folgt ändern:

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; 
} 

Dann für den Test können Sie

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

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

Für Spottunterprogramme verwende ich lieber http://search.cpan.org/~gfranken/Test-MockModule-0.11/lib/Test/MockModule.pm – bart