Mocking Static Functions
Mocking Static Functions in Lucee
Understanding Static Functions in Lucee
In Lucee, static functions belong to the component definition rather than a specific component instance. This means they can be called directly using the component name:
// Test.cfc
component {
public static function myStaticFunction() {
return "static";
}
}
Calling the static function:
dump(Test::myStaticFunction()); // Outputs: "static"
Unlike instance functions, static functions:
- Do not require an object instance to be called.
- Are shared across all instances of the component.
- Can be accessed exactly like instance functions.
Accessing Static Functions via Instances
In Lucee, a static function can also be accessed through an instance of the component, just like an instance function:
testInstance = new Test();
dump(testInstance.myStaticFunction()); // Outputs: "static"
Mocking Static Functions
One key advantage of this behavior is that static functions can be mocked just like instance functions.
Example:
testInstance = new Test();
// overlay static function with different behaviour
testInstance.myStaticFunction = function() {
return "mockstatic";
};
dump(Test::myStaticFunction()); // Outputs: "static"
dump(testInstance.myStaticFunction()); // Outputs: "mockstatic"
Why This Matters for Testing
- There is no need to create instance wrapper functions for static functions.
- Static functions can be dynamically mocked per instance without modifying the component.
- This allows for cleaner test code and avoids unnecessary duplication.
Retrieving Static and Instance Function Metadata
Lucee provides a way to retrieve metadata for both static and instance functions using getMetadata. The structure of the returned metadata is identical for both, with the only difference being a static flag:
testInstance = new Test();
dump(getMetadata(testInstance).functions);
Example output:
[
{"name": "myInstanceFunction", "static": false,...},
{"name": "myStaticFunction", "static": true,...}
]
This means that static and instance functions are represented the same way in metadata, with the static flag indicating whether a function is static or not.
The Benefit of Static Functions
- No Difference in Access – Static functions work exactly like instance functions.
- Ease of Mocking – Static functions can be mocked at the instance level, avoiding unnecessary wrappers.
- Consistency – Static functions ensure a uniform implementation across instances while still allowing for instance-level customization when needed.
- Overlay vs. Overwrite – When an instance function is redefined (mocked), it overwrites the original implementation for that instance. With static functions, defining an instance-level function of the same name overlays the static function for that instance only, while the original static function remains accessible via the component definition.