8

いくつかの定数を宣言したPerlモジュールがあります。

use constant BASE_PATH => "/data/monitor/";

ライブ操作では定数は変更されませんが、単体テストで変更できるようにしたいと思います。たとえば、に設定し~/project/testdata/ます。グローバルな可変変数を使用せずにこれを行う方法はありますか?

私はおそらくで使用できTest::MockObjectますconstantか?

4

5 に答える 5

6

定数を使用する場合、次のような動作をする定数関数として実装されます。

use subs 'BASE_PATH';
sub BASE_PATH () {"/data/monitor/"}

プログラムでの BASE_PATH の使用はすべてインライン化されているため、変更できません。

同様のことを実現するには、subs プラグマを手動で使用して (BASE_PATH を組み込み関数として動作させるため)、BASE_PATH を標準関数として宣言します。

use subs 'BASE_PATH';
sub BASE_PATH {"/data/monitor/"}

print "BASE_PATH is ".BASE_PATH."\n";

*BASE_PATH = sub {"/new/path"};
print "BASE_PATH is ".BASE_PATH."\n";

なぜあなたがこれをやりたいのか、私にはよくわかりません。

于 2009-07-01T16:16:34.287 に答える
5

テストによって、設計の柔軟性の欠如が明らかになることがよくあります。これはそれらの時間の 1 つです。その定数は定数であってはなりません。

パフォーマンス上の理由でそれを行っているのであれば、私はそれが何の違いももたらさないことを確信しています。

于 2009-07-03T07:51:39.150 に答える
3
パッケージ My::Class;

定数 BASE_PATH を使用 => "/a/real/value/";

# ..その他のコードはこちら..

1;

ユニットテストで:

My::Class を使用します。
*{My::Class::BASE_PATH} = sub { "/a/fake/value" };

# ここでテストを行います...
于 2009-07-02T23:26:13.547 に答える
1

どうやら、テストがそれを変更する前に、BASE_PATHの定義が使用/別のサブルーチンにコンパイルされた場合(

*BASE_PATH = sub { ... }

または他のもの) 解決策がありません (元のモジュールが定数として BASE_PATH を使用していたとき、他のコードで使用されたときにインライン化された INLINE 関数を実際に定義したため)

于 2009-07-01T19:16:24.227 に答える