Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to override a Perl "use constant" in your unit testing?

I have a Perl module that I have declared some constants:

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

In live operation the constant will never change but I wish to be able to modify it in my unit tests, e.g. to set it to ~/project/testdata/. Is there a way do do this without having to use global mutable variables?

Could I possibly use Test::MockObject on the constant?

like image 508
Vagnerr Avatar asked Jul 01 '09 15:07

Vagnerr


People also ask

Should you use constants in unit tests?

Every developer wants to promote code reuse. Generally, reuse is a good thing. It makes for more maintainable and more correct code.

What is Perl constant?

Constants may be lists of more (or less) than one value. A constant with no values evaluates to undef in scalar context. Note that constants with more than one value do not return their last value in scalar context as one might expect. They currently return the number of values, but this may change in the future.


2 Answers

When using constants they are implemented as constant functions behaving something like:

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

Any uses of BASE_PATH in the program are inlined and so can't be modified.

To achieve similar you could manually use the subs pragma (to make BASE_PATH behave as a built in function) and declare BASE_PATH as a standard function:

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

Although why you would want to do this I'm not too sure.

like image 84
Callum Avatar answered Oct 07 '22 19:10

Callum


Tests often reveal inflexibility in the design. This is one of those times. That constant shouldn't be constant.

If you're doing it for performance reasons I'm willing to bet hard currency that it doesn't make any difference.

like image 41
Schwern Avatar answered Oct 07 '22 20:10

Schwern