2017-04-25 70 views
4

我正在編寫一個P4Perl腳本來連接Perforce服務器並自動執行Perforce命令。隨着訪問Perforce的子例程的開發,我還在開發單元測試來驗證它們。我對Perl和單元測試都很陌生。

這是我建立Perforce連接的子程序。文件名是p4_connect.pl

use warnings; 
use strict; 

use P4; 

my $clientname = "johndoe" 
my $p4port = "icmanage:1667" 

main(); 

sub main { 
    my $status; 
    $status = connect_perforce($clientname, $p4port); 
}; 

sub connect_perforce { 

    my ($clientname, $p4port) = @_; 
    my $status; 
    my $p4 = new P4; 

    $p4->SetClient($clientname); 
    $p4->SetPort($p4port); 
    $status = $p4->Connect() or die("Failed to connect to Perforce Server"); 

    return $status; 
} 

當我運行"perl p4_connect.pl"的Perl腳本執行很好,沒有錯誤拋出。

然而,當我移動connect_perforce子程序包模塊(Perforce.pm)和寫單元測試(perforce.t)它,我遇到這些錯誤:

[email protected]% perl -Ilib t/perforce.t 
ok 1 - use Perforce; 
ok 2 - Perforce->can('connect_perforce') 
Connect to server failed; check $P4PORT. 
TCP connect to johndoe failed. 
Servname not supported for ai_socktype 
Failed to connect to Perforce Server at lib/Perforce.pm line 16. 

這是單元測試(perforce.t)的樣子:

use Perforce; 

use warnings; 
use strict; 
use Test::More qw(no_plan); 

use P4; 

BEGIN { use_ok('Perforce'); } #package can be loaded 

can_ok('Perforce', 'connect_perforce'); #subroutine connect_perforce exists 

my $p4port = "icmanage:1667"; 
my $p4 = Perforce->connect_perforce(qw(johndoe $p4port)); #accessing the connect_perforce() subroutine 

這是我的包(Perforce.pm)看起來像:

package Perforce; 

use warnings; 
use strict; 

use P4; 

    sub connect_perforce { 

    my ($clientname, $p4port) = @_; 
    my $status; 
    my $p4 = new P4; 

    $p4->SetClient($clientname); 
    $p4->SetPort($p4port); 
    $status = $p4->Connect() or die("Failed to connect to Perforce Server"); 

    return $status; 
} 

我的單元測試在哪裏出錯?任何建議都有幫助。

+0

不知道這是否是相關的,但你的程序集之一'$ p4port'到'icmanage.com:雖然1667',另一個將它設置爲'icmanage:1667'。順便提一句,「ai_socktype不支持Servname」使得您的問題聽起來非常類似於http://stackoverflow.com/questions/23079017/servname-not-supported-for-ai-socktype。這個消息讓我想到一些網絡軟件庫試圖在網絡配置文件中找到'icmanage'服務? –

+0

我很抱歉,這是一個錯字。已正確更正 –

+1

「新P4」應該是帶有箭頭的「P4->新」。這是代碼中您應該擁有該箭頭的唯一地方,因爲間接對象符號是不明確的。 :) – simbabque

回答

5

您正在混合面向對象的Perl和函數式Perl,並且您已經成爲它的受害者。

當您使用箭頭運算符->作爲方法調用函數時,Perl將左側的東西作爲第一個參數傳遞給函數。如果是包名稱,那只是包名稱。

package Foo; 
sub frobnicate{ print "@_" } 

package main; 
Foo->frobnicate(1, 2, 3); 

的這個輸出將是

Foo 1 2 3 

所以你的情況,connect_perforce會得到這樣分配:

my ($clientname, $p4port) = ('Perforce', 'johndoe', 'icmanage:1667'); 

所以變量將是這些值:

$clientname: 'Perforce' 
$p4port:  'johndoe' 

而你的'icmanage:1667'字符串會丟失。

如果您沒有物件,請勿使用箭頭。調用此函數的正確方法(不是方法!)是使用包含該包的完全限定名稱。

my $p4 = Perforce::connect_perforce('johndoe', $p4port); 

我已經刪除了這個相當奇怪的qw()。它會給你一個文字$p4port而不是值,所以這是你接下來會遇到的另一個bug。

由於我們確定您沒有班級,而是一個模塊,因此您也不想使用can_ok。這不是你的用例的正確測試。相反,只需調用上面顯示的函數,然後使用返回的值進行有用的測試。如果該功能不存在,測試程序將失敗,您會注意到。

BEGIN { use_ok('Perforce'); } 

my $p4 = Perforce::connect_perforce('johndoe', 'icmanage:1667'); 

isa_ok($p4, 'P4'); # I guess.. 

有關對象方向和上模塊的更多信息,看看perlobjperlootutperlnewmodExporter。 Perlmaven也有some good articles


1)它做更多,但是這不是與此有關

+1

這是一個非常明確的解釋 –