Testing for errors

The -Throw assertion is used to test whether a block of code throws a terminating error. Throw has a number of different usage scenarios. The simplest is detecting whether a terminating error (of any kind) is thrown at all:

function Invoke-Something {
throw
}

Describe Invoke-Something { It 'Throws a terminating error' { { Invoke-Something } | Should Throw } }

When testing for terminating errors, the subject of the test is placed in a script block (curly braces).

The next step might be to get Pester to test the error message, to ensure that the right error is thrown:

function Invoke-Something {
throw 'an error'
}

Describe Invoke-Something { It 'Throws a terminating error' { { Invoke-Something } | Should Throw 'an error' } }

If a module is written with localization in mind, the error message might not be particularly reliable. A trivial change to the message, such as a punctuation change, may break the test. Two alternative approaches are available: testing the exception type and testing the error ID. 

Testing the exception type may be useful if the command raises different exception types for each operation. For example, this command raises one of two different exceptions, depending on the value of a parameter:

function Invoke-Something {
param (
$value
)

if ($value -isnot [Int32]) {
throw [ArgumentException]::new('The value must be an integer')
}
if ($value -ge 100) {
throw [ArgumentOutOfRangeException]::new('The value must be less than 100')
}
}

Describe Invoke-Something {
It 'When the value is not an integer, throws an ArgumentException' {
{ Invoke-Something -Value none } | Should -Throw -ExceptionType ArgumentException
}

It 'When the value is greater or equal to 100, throws an ArgumentOutOfRange exception' {
{ Invoke-Something -Value 100 } | Should -Throw -ExceptionType ArgumentOutOfRangeException
}
}
This is bad parameter validation

The preceding example is contrived. It demonstrates testing errors raised by a common in Pester. This example should not be considered a reasonable way to constrain and validate a parameter value.

Pester also allows for the testing of the fully qualified error ID. For this approach to be beneficial, the subject of the test must define a reasonable set of fully qualified error IDs:

function Invoke-Something { 
    $errorRecord = [System.Management.Automation.ErrorRecord]::new( 
        [InvalidOperationException]::new('an error'), 
        'AUniqueErrorID', 
        'OperationStopped', 
        $null 
    ) 
    throw $errorRecord 
}
Describe Invoke-Something { It 'Throws a terminating error' { { Invoke-Something } | Should -Throw -ErrorId 'AUniqueErrorId' } }

If a function is written such that it writes a non-terminating error (using Write-Error), and the generation of that error must be tested, two possible approaches are available.

The ErrorVariable parameter might be used to capture, and then test, as follows:

function Invoke-Something { 
    [CmdletBinding()] 
    param ( )
Write-Error 'Error' -ErrorId 'NonTerminating' }

Describe Invoke-Something { It 'Throws a non-terminating error' { Invoke-Something -ErrorAction SilentlyContinue -ErrorVariable testError
$testError.Count | Should -Be 1
$testError.FullyQualifiedErrorId | Should -Match 'NonTerminating'
}
}

Or, ErrorAction may be used, influencing whether the error is raised:

function Invoke-Something { 
    [CmdletBinding()] 
    param ( )
Write-Error 'Error' -ErrorId 'NonTerminating' }
Describe Invoke-Something { It 'Throws a non-terminating error' { { Invoke-Something -ErrorAction SilentlyContinue } | Should -Not -Throw -ErrorId 'NonTerminating' { Invoke-Something -ErrorAction Stop } | Should -Throw -ErrorId 'NonTerminating' } }
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
13.58.248.239