在单元测试中,有没有一种方法可以替代Perl的“使用常量”?不稳定

问题描述 投票:5回答:5

我有一个已经声明了一些常量的Perl模块:

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

在实时操作中,常量将从不发生变化,但我希望能够在我的单元测试中对其进行修改,例如将其设置为~/project/testdata/。有没有一种方法而不必使用全局可变变量?

我可以在Test::MockObject上使用constant吗?

unit-testing perl mocking constants compile-time-constant
5个回答
6
投票

使用常量时,它们被实现为常量函数,其行为类似于:

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";

尽管我不太确定为什么要这么做。


5
投票

测试通常会揭示设计的灵活性。这是那些时代之一。该常数不应该是常数。

如果您出于性能原因这么做,我愿意打赌硬货币不会带来任何改变。


2
投票
包My :: Class;使用常量BASE_PATH =>“ / a / real / value /”;#..更多代码在这里..1;

现在在单元测试中:

使用My :: Class;* {My :: Class :: BASE_PATH} = sub {“ / a / fake / value”};#在这里做测试...

2
投票

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/'; 的作者,但我遇到了同样的问题。


1
投票

显然,如果您的BASE_PATH定义已使用/编译到另一个子例程中,则您的测试确实更改了它(通过)>

unconstant

或其他东西)您没有解决方案(因为当原始模块使用BASE_PATH作为常量时,它确实定义了一个INLINE函数,当在其他代码中使用时,该函数可以被内联)]

© www.soinside.com 2019 - 2024. All rights reserved.