Mocking Missing Cmdlets with Pester

When writing Pester unit tests for your Powershell code you will probably have a need to mock calls to external functions before too long. This process works as you would expect when Pester can locate a defined function/cmdlet with a matching name. However, if Pester cannot find a definition, it will fail.

This problem will normally surface in a Continuous Integration (CI) environment. For me, it was writing the first suite of tests for the xHyper-V DSC resource module. The Hyper-V cmdlets where present on my authoring machine but were not present on the Appveyor build VM.

Here is an overly simplified Pester test that I’ll use for demonstration purposes:

If we run the test and Pester cannot locate a defined function then it will report an error. Note: if you run this on a machine with the Hyper-V module installed (and you have a VM called ‘TestVM’) then it will pass – but you knew that already ;).

This is easily overcome by defining an empty function within the test file. Note: this will need to be defined within the ‘InModuleScope’ script block if you’re testing a module’s internals.

The test now passes as we would expect. Yay \o/

Now, what you really need to know is that for Pester to enumerate and mock parameter filters, those parameters need to be defined on the stub function. If we were to update the test to check for the passing of a particular –Name parameter like so:

When we run the test it will now fail again.

For Pester to enumerate the dynamic parameters on the function, it needs to have the parameters (only the one’s you’re interested in) defined. This can easily be fixed like so:

The tests will now once again pass successfully!

Hopefully this helps someone and saves some time. It took me a while to work out what was going on as I had the cmdlets available on my development machine but the tests were failing when running in an Appveyor VM. Perhaps I should submit a pull request to get this put into the Pester help documentation?!

2 Comments

  1. JsemDroidik (@JsemDroidik) Author September 6, 2015 (9:15 pm)

    I would prefer some kind of parameter like -Force for Mock cmdlet to work with unknown cmdlets. What do you think?

  2. Matt Author May 12, 2016 (9:14 am)

    Outstanding I was facing this issue and your post was the first one I found and it has solved my issue. I knew I could override with the function but was missing the InModuleScope script. Thanks

Leave a Reply

Archives

Categories