Pester Mocking, ParameterFilters and Write-Output

I just spend an annoyed 45 minutes or so puzzling over a Pester test I was writing. I needed to test an if/elseif/else branching block of PowerShell code, written by someone else, which did very similar things to install powershell modules, uninstall, reinstall, or not, depending on some evaluated conditions and based on a list of modules and their versions

The final else condition was, in essence, not doing anything other than writing to the output stream to say “I’m not doing anything at this point”, so obviously I figured I could use Assert-MockCalled on Write-Output and I’d know what path the code was going down and I’d be sorted.

Anything but.

Here’s roughly what I tried first up

It "Should write 'doing nothing' to the screen" {
    Assert-MockCalled Write-Output -ParameterFilter { $Message -eq "doing nothing" }

Yeah, that didn’t work. Expected Write-Output to be called at least 1 times. It was called 0

OK, so yeah, Write-Output doesn’t have a $Message parameter – That’s Write-Verbose you’re thinking of. Try $args[0]

It "Should write 'doing nothing' to the screen" {
    Assert-MockCalled Write-Output -ParameterFilter { $args[0] -eq "doing nothing" }

Argh. Same problem.

OK, let’s use the Get-Parameter cmdlet from Carbon.

    Command: Microsoft.PowerShell.Utility/Write-Output
    Set:    Default

Name                   Aliases      Position Mandatory Pipeline ByName Provider        Type
----                   -------      -------- --------- -------- ------ --------        ----
InputObject            {Inp*}       0        True      True     False  All             PSObject[]
NoEnumerate            {N*}         Named    False     False    False  All             SwitchParameter

OK, so it’s an input object, and it’s an array of objects I fooled around with that for a little while and I ended up with this ugly mess. It works, at least:

Assert-MockCalled Write-Output -ParameterFilter { $InputObject[0].ToString() -like "*installing module $($targetmodule.Name)*" }

What’s the moral of this story other than “Mocks are evil”? Well, I guess the moral is “know how to use PowerShell to reflect its own information back out”. Cmdlets like Get-Help, Get-Command, Get-Member and their distant relations are worth their weight in gold and you should have them at your fingertips all the time.






Leave a Reply

Your email address will not be published. Required fields are marked *