2017-06-28 15 views
4

unlinkrenameのような組み込み演算子をテストスイートの一部としてモックする必要があります。私は、これは、このような組み込み関数を模擬することが可能ですTest::MockObject組み込み演算子をモックする方法

>> my $mock = Test::MockObject->new(); 
>> $mock->mock('unlink', sub { print "Mocked!\n"; }); 
>> unlink "foo"; 
0 

使用して動作させることはできませんか?

答えて

5

overriding core functions参照してください:Perlを上書きするには

は内蔵のルーチン独自のバージョンでは、コンパイル時にそれをインポートする必要があります。これは、subsプラグマを使用すると便利です。これは、あなたが言ったサブルーチンインポートしたしたパッケージのみ影響します:組み込みのグローバルを上書きするには

use subs 'chdir'; 
    sub chdir { ... } 
    chdir $somewhere; 

を(つまり、すべての名前空間では、ある)、あなたはCORE::GLOBAL擬似にあなたの関数をインポートする必要がありますコンパイル時に名前空間:

BEGIN { 
     *CORE::GLOBAL::hex = sub { 
      # ... your code here 
     }; 
    } 

組み込み関数は、予選パッケージなしで呼び出されるたびに新しいルーチンが呼び出されます:両方のC言語で

print hex("0x50"),"\n";   # prints 1 

print CORE::hex("0x50"),"\n";  # prints 80 

も参照してくださいthe relevant section in perldoc perlsub

あなたはビルトインをオーバーライドする場合は、あなたの交換が一貫している必要がありアーゼは、あなたが元、変更されていないルーチンにアクセスしたい場合は、CORE::接頭辞を使用します(可能であれば)組み込みのネイティブ構文を使用します。これは、適切なプロトタイプを使用することで実現できます。オーバーライド可能なビルトインのプロトタイプを取得するには、引数が "CORE::builtin_name"(prototype参照)のプロトタイプ関数を使用します。

しかし、一部の組み込み関数は、プロトタイプ(システムやchompなど)で表現された構文を持つことはできません。それらを上書きすると、元の構文を完全に模倣することができなくなります。

組み込み関数dorequireglob canも上書きすることが、原因特殊な魔法に、元の構文は保存され、あなたはその代替のためのプロトタイプを定義する必要はありません。 (ただし、do BLOCKの構文は無効にできません)。

requireは、特別な追加の黒魔術を持っている:あなたはrequire Foo::Barとしてあなたrequire交換を起動した場合、それが実際に@_で引数"Foo/Bar.pm"を受け取ることになります。 requireを参照してください。

上記の例から気が付いたように、globを上書きすると、<*> glob演算子も上書きされます。

同様の方法で、readline関数をオーバーライドすると、同等の入出力演算子<FILEHANDLE>もオーバーライドされます。また、readpipeをオーバーライドすると、演算子 "およびqx//も上書きされます。

最後に、一部のビルトイン(例:existsまたはgrep)を上書きすることはできません。

+0

パーフェクト!後で機能を解除することは可能ですか? – ewok

+0

確かに 'use subs 'chdir''は' sub chdir; 'で宣言するのと同じですが、定義が呼び出しの前に来る場合はどちらも必要ありません。その勧告は主要な点とは別のようです。 – Borodin

+0

注:* [subsを使用する]は、上記のサブルーチンをインポートしたパッケージのみに影響します* "...他にも必要な場合は、コードを表示してください。 –

関連する問題