Search code examples
powershellexceptionthrowpesterpester-5

How do I check if a specific exception type has been thrown in Pester 5.4.0?


I want to write a test in PowerShell with Pester 5.4.0 to check whether a specific exception type has been thrown inside a script block. It should be fairly easy, but I am somehow not doing it right. Following along the Pester v5 documentation for the Should keyword and this pre-release Pester blogpost about using Should - Throw I wrote the following (very basic) script containing one test:

Import-Module Pester -RequiredVersion 5.4.0

Describe "Testing if a service is registed." {
    It "This service should not be registered in the windows services app." {
        { Get-Service -Name "this service does not exist" } | Should -Throw -ExceptionType ([Microsoft.PowerShell.Commands.ServiceCommandException])
    }
}

I would expect the test to catch the ServiceCommandException that is thrown when the Get-Service Cmdlet looks for a service that does not exist, and the test to pass. Instead the error is still thrown, Pester tells me that Expected an exception, with type [Microsoft.PowerShell.Commands.ServiceCommandException] to be thrown, but no exception was thrown., and the test fails:

enter image description here

I am probably doing something that's very obvious wrong here, but I looked at it for a while and did some research, and I cannot see what is wrong with my script.


Solution

  • the type of error you get from get-service is not a throwing/operation halting error. This means that while there is an error, Powershell will continue to process your script until completed.

    to make sure that any command actually halts operation and triggers pesters should -throw, you can add -erroraction stop or the alias -ea stop to the get-service command: enter image description here

    The issue here, however you want to look at it, is that you are testing if a command is throwing an error, and handling it this way. however the command does not throw anything. it returns an error. its not a operation stopping thing that happens (even though you can force it by setting -erroraction).

    what you might want to do instead is this:

    It "Testing other method" {
        Get-Service -Name "this service does not exist" -ErrorVariable er -ErrorAction SilentlyContinue
        $er|should -not -HaveCount 0
        $er.Exception|Should -BeOfType ([Microsoft.PowerShell.Commands.ServiceCommandException])
    }