2
Set-Location "C:\thisDirDoesNotExist"
If(-not $?)
{
    Write-Error -Message "error"
    Exit 1
}

How do I mock a command failing? In the above code, the Set-Location command will error with a non-terminating error. The $? variable will be set to false and an error message will be outputted and the script will exit.

How do I mock the Set-Location command to set the $? variable to false?

3 Answers3

0

You could use the -ErrorVariable parameter. In the following example, the variable $locationError will be set when Set-Location cmdlet fails:

Set-Location "C:\" -ErrorVariable locationError
If($locationError)
{
    Write-Error -Message "error"
    Exit 1
}

Now all you have to do is to set $locationErrorto $true to mock your failure.

Martin Brandl
  • 56,134
  • 13
  • 133
  • 172
  • I've tried "Mock Set-Location { $locationError = $true }" but when I get to the if statement that checks $locationError , the $locationError variable is empty. – TheTerribleProgrammer May 17 '16 at 13:04
  • Ah, I missed that part that you are working with pester. However, if you throw an exception within your Set-Location mock it should work. – Martin Brandl May 17 '16 at 13:05
  • 2
    I got there in the end, you pointed me in the right direction with this. So I used the code you provided, but in the mock I used the following: "Set-Location { Write-Error "Error" }". This will populate the $locationError variable. – TheTerribleProgrammer May 17 '16 at 13:17
0

You can use Throw to force whatever error you want. $? will be False after the Throw.

mjolinor
  • 66,130
  • 7
  • 114
  • 135
0

Usually, a mock to produce an error, with a test to verify you got the error looks like this:

Test code

Describe 'mock an error' {
    Context 'terminating error' {
        Mock -CommandName Set-Location -MockWith {Write-Error 'My Error' -ErrorAction 'Stop'} 

        it 'should throw' {
            {Set-Location -Path .\foo -ErrorAction Stop} | should throw 'My Error'
        }
    }

    Context 'non-terminating error' {
        Mock -CommandName Set-Location -MockWith {Write-Error 'My Error' } 

        it 'should throw' {
            {Set-Location -Path .\foo -ErrorVariable slError
            $Global:slError=$slError} | should not throw
            $global:slError.count |should be 1
            $Global:slError[0].Exception.Message | should be 'My Error'
        }
    }
}

Results

Describing mock an error
   Context terminating error
    [+] should throw 551ms
   Context non-terminating error
Write-Error 'My Error'  : My Error
At C:\Program Files\WindowsPowerShell\Modules\Pester\3.4.0\Functions\Mock.ps1:1056 char:9
+         & $___ScriptBlock___ @___BoundParameters___ @___ArgumentList_ ...
+         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException

    [+] should throw 164ms
TravisEz13
  • 2,263
  • 1
  • 20
  • 28