Search code examples
unit-testingperlmockingconstantscompile-time-constant

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?


Solution

  • 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.