2009-10-08 7 views

答えて

32

UPDATE: IMHO、この質問に対する正しい答えはTest::Outputを使用するためにであるべきだ:

#!/usr/bin/perl 

use strict; use warnings; 

use Test::More tests => 1; 
use Test::Output; 

sub myfunc { print "This is a test\n" } 

stdout_is(\&myfunc, "This is a test\n", 'myfunc() returns test output'); 

出力:

 
C:\Temp> tm 
1..1 
ok 1 - myfunc() returns test output 

私は、として参照のためのオリジナルの答えを残しています私は信じています、それはまだ役に立つテクニックを示しています

あなたはその後、復元、関数を呼び出す前にSTDOUTをローカライズし、スカラーに再度開くことができます。

#!/usr/bin/perl 

use strict; use warnings; 

use Test::More tests => 1; 

sub myfunc { print "This is a test\n" } 

sub invoke { 
    my $sub = shift; 
    my $stdout; 
    { 
     local *STDOUT; 
     open STDOUT, '>', \$stdout 
      or die "Cannot open STDOUT to a scalar: $!"; 
     $sub->(@_); 
     close STDOUT 
      or die "Cannot close redirected STDOUT: $!"; 
    } 
    return $stdout; 
} 

chomp(my $ret = invoke(\&myfunc)); 

ok($ret eq "This is a test", "myfunc() prints test string"); 
diag("myfunc() printed '$ret'"); 

出力:5.8より古いperlのバージョンの

 
C:\Temp> tm 
1..1 
ok 1 - myfunc() prints test string 
# myfunc() printed 'This is a test' 

、あなたはおそらく使用する必要がありますIO::Scalarですが、私は5.8より前にはどのように働いたのか分かりません。

+4

ちょうど私があまりにも多くの時間を無駄にしていると思うとき、私は何かクールなことを学ぶ!ありがとう。 – FMc

+0

さて、技術的にはそうではありませんが、彼らがそうしていると確かにいいです。 :p(+1、それはすばらしいモジュールです) –

+0

私はそれをdownvoteしませんでしたが、私は元の答えはあまりにも仕事を完了するために働くと思います。それはあまりにも複雑です。私は少しTest :: Outputに偏っていますが、最後の手段として使用します。有用性のためには+1 –

7

私は、モジュールでこれを処理させることにします。 Capture::Tinyを見てください。

+0

+1私はCapture :: Tinyについて知らなかった。 –

5

これは自分で作成したコードの場合は、print文でデフォルトのファイルハンドルを使用しないように変更します。あなたがテストする際

 
sub my_print { 
    my $self = shift; 
    my $fh = $self->_get_output_fh; 
    print { $fh } @_; 
    } 

sub _get_output_fh { $_[0]->{_output} || \*STDOUT } 
sub _set_output_fh { $_[0]->{_output} = $_[1] } # add validation yourself 

、あなたはそれをあなたのテストファイルハンドル(おそらくIO::Nullハンドル)を得_set_output_fhを呼び出すことができます。その代わり、自分であなたが好きなものへの出力ファイルハンドルを設定する方法を与えます。別の人があなたのコードを使用したいが、出力をキャプチャしたいときは、独自のファイルハンドルを与えることができるので、後ろに曲がる必要はありません。

コードの一部をテストするのが難しい、または作業するためにフープを飛ばしなければならないときは、おそらくデザインが悪いでしょう。私は、テストコードがこれらのことを明らかにする方法にはまだびっくりしています。なぜなら、私はしばしばそれらについて考えることがないからです。テストするのが難しい場合は、簡単にテストしてください。あなたがそれをするならば、あなたは一般的に勝ちます。

+0

Amen。単体テストを書く(あるいは、TDDを行う場合は、それを知っているかどうかに関わらず計画を立てる)ことは、デザインの改善が著しいことになります。 – DVK

関連する問題