Few days ago I posted about a tiny module I wrote to skip the entry point function in a script. I got few reactions telling me that there are better ways to organize your scripts, and they were all correct. Putting your code into a module and distributing it that way, or splitting the script into different files and combining them during build are both better than having a single file with everything.
The post was not a recommendation how to write your scripts all the time, instead it just described a technique that you can use when needed. One such case is when you are providing scripts to others that do not know PowerShell. Providing a single self-contained script is simpler than distributing, importing and invoking a module. I also find it useful for build scripts, or scripts in scheduled tasks.
Testing entry point function invocation
There are probably other possible use cases, but this is the one I am using this module for. To test that parameters are passed correctly to the entrypoint function. In my case the entrypoint function does an involved, and destructive action, so I cannot simply invoke the whole script and check result, without setting up the whole environment for it.
Below I will show the same thing on a function that has non-destructive behavior, so a better way to test it would be to simple invoke the whole script and check the result. So keep that in mind.
# file script1.ps1 |
Our Get-Avocado
function was renamed to Get-Fruit
and now can return different emojis, or a random one. I am invoking it from the script and passing some mandatory parameters, in two parameter sets.
# file script1.Tests.ps1 |
In the test I am then importing the script, passing in the Random
switch, to make sure I am able to run the script. The call to Get-Fruit
is still replaced by the mock so I am able to import the script without ever invoking Get-Fruit
.
At that moment I have the Get-Fruit
imported to my local scope and can mock it. Which in turn means that I can test just the param
block on the top of the script.
Summary
This admittedly tests just a tiny slice of the script, but a bit that would be impossible to test otherwise. Go ahead and try to comment out the invocation of the Get-Fruit
function. You should see that all the unit tests still pass, but the script does nothing. And that is the whole goal, to be able to test every single line of the code. You donβt have to do it, but it is nice to have the possibility.