我有一个已经声明了一些常量的Perl模块:
use constant BASE_PATH => "/data/monitor/";
在实时操作中,常量将从不发生变化,但我希望能够在我的单元测试中对其进行修改,例如将其设置为~/project/testdata/
。有没有一种方法而不必使用全局可变变量?
我可以在Test::MockObject
上使用constant
吗?
使用常量时,它们被实现为常量函数,其行为类似于:
use subs 'BASE_PATH';
sub BASE_PATH () {"/data/monitor/"}
程序中对BASE_PATH的任何使用都已内联,因此无法修改。
要获得类似的效果,您可以手动使用subs pragma(使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";
尽管我不太确定为什么要这么做。
测试通常会揭示设计的灵活性。这是那些时代之一。该常数不应该是常数。
如果您出于性能原因这么做,我愿意打赌硬货币不会带来任何改变。
包My :: Class;使用常量BASE_PATH =>“ / a / real / value /”;#..更多代码在这里..1;
现在在单元测试中:
使用My :: Class;* {My :: Class :: BASE_PATH} = sub {“ / a / fake / value”};#在这里做测试...
unconstant
一种简单的方法是使用unconstant
。
unconstant
免责声明:我是# From ./lib/Foo.pm
package Foo {
use constant BASE_PATH => '/data/monitor/';
}
# From test.pl
use unconstant; # Do this first
use Foo;
use constant *Foo::BASE_PATH => '/otherData/otherMonitor/';
的作者,但我遇到了同样的问题。
显然,如果您的BASE_PATH定义已使用/编译到另一个子例程中,则您的测试确实更改了它(通过)>
unconstant
或其他东西)您没有解决方案(因为当原始模块使用BASE_PATH作为常量时,它确实定义了一个INLINE函数,当在其他代码中使用时,该函数可以被内联)]