Search code examples
powershellpester

Pester fails test even when exception is caught


I have a utility function that specifically handles an exception and ignores it, but when testing it with Pester the test fails, showing the exception that was already caught and handled. Am I missing something, or is this a bug in Pester?

This code reproduces the issue:

function Test-FSPath {

    [cmdletbinding()]
    param([string]$FileSystemPath)

    if([string]::IsNullOrWhiteSpace($FileSystemPath)) { return $false }

    $result = $false
    try {  
        if(Test-Path $FileSystemPath) {
            Write-Debug "Verifying that $FileSystemPath is a file system path"
            $item = Get-Item $FileSystemPath -ErrorAction Ignore
            $result = ($item -ne $null) -and $($item.PSProvider.Name -eq 'FileSystem')        
        }
    } catch {
        # Path pattern that Test-Path / Get-Item can't handle 
        Write-Debug "Ignoring exception $($_.Exception.Message)" 
    }

    return ($result -or ([System.IO.Directory]::Exists($FileSystemPath)) -or ([System.IO.File]::Exists($FileSystemPath)))
}

Describe 'Test' {
    Context Test-FSPath { 
        It 'returns true for a path not supported by PowerShell Test-Path' {
            $absPath = "$env:TEMP\temp-file[weird-chars.txt"
            [System.IO.File]::WriteAllText($absPath, 'Hello world')
            $result = Test-FSPath $absPath -Debug
            $result | Should -Be $true 
            Write-Host "`$result = $result"
            Remove-Item $absPath
        } 
    }
}

Expected result: Test passes

Actual result: Test fails:

[-] returns true for a path not supported by PowerShell Test-Path 2.62s
  WildcardPatternException: The specified wildcard character pattern is not valid: temp-file[weird-chars.txt
  ParameterBindingException: Cannot retrieve the dynamic parameters for the cmdlet. The specified wildcard character pattern is not valid: temp-file[weird-chars.txt

Solution

  • The exception you're seeing is not coming from your function, its coming from your use of Remove-Item which is throwing the error trying to remove the erroneous path (which also doesn't exist). You should just remove it as you never expect the item to be created anyway.

    Or, alternatively (as mentioned in the comments) use TestDrive: which you then don't need to worry about cleaning up (seems for the path to be supported you need to use $Testdrive).

        It 'returns true for a path not supported by PowerShell Test-Path' {
            $absPath = "$env:TEMP\temp-file[weird-chars.txt"
            [System.IO.File]::WriteAllText($absPath, 'Hello world')
            $result = Test-FSPath $absPath
            $result | Should -Be $true 
        } 
    

    As an aside, I generally tend to do execution type stuff outside of the It, and just test the result inside. When I started to do this for your code it showed me that the test was passing, as the error then moved to occurring in the Context block. Here's what I mean (also this example makes use of TestDrive: via the $testdrive variable):

    Describe 'Test' {
        Context Test-FSPath { 
            $absPath = "$testdrive\temp-file[weird-chars.txt"
            [System.IO.File]::WriteAllText($absPath, 'Hello world')
            $result = Test-FSPath $absPath
    
            It 'returns true for a path not supported by PowerShell Test-Path' {
                $result | Should -Be $true 
            } 
        }
    }