Search code examples
powershellunit-testingpester

Pester test if the module is existing. Should not throw specific ExceptionType


Is it only me or the Pester if extremely hard to grab?

In the BeforeAll scriptblock I would like to test if the ActiveDirectory module is existing on the local machine.

The test should not throw exception type [System.IO.FileNotFoundException]

Question 1:

What is the correct/best approach?

Get-Module Module| Remove-Module -Force
Import-Module Module
Import-Module Pester

InModuleScope Module{

    Describe 'Add-Patchgroup' {

        BeforeAll {
            It 'Should import module ActiveDirectory' {
                {Import-Module -Name ActiveDirectory -ErrorAction Stop } | Should -Not -Throw -ExceptionType {[System.IO.FileNotFoundException]}
            }
        }
    }
}

Error when I run this on machine where AD module is not available:

Describing Add-Patchgroup
  [-] Should import module ActiveDirectory 99ms
    PSInvalidCastException: Cannot convert the "[System.IO.FileNotFoundException]" value of type "System.Management.Auto
mation.ScriptBlock" to type "System.Type".
    ArgumentTransformationMetadataException: Cannot convert the "[System.IO.FileNotFoundException]" value of type "Syste
m.Management.Automation.ScriptBlock" to type "System.Type".
    ParameterBindingArgumentTransformationException: Cannot process argument transformation on parameter 'ExceptionType'
. Cannot convert the "[System.IO.FileNotFoundException]" value of type "System.Management.Automation.ScriptBlock" to typ
e "System.Type".

Question 2:

Also consider there is a module named ComplexModule which is very time consuming to Import. Therefore I would like to mock the Import-Module -Name ComplexModule cmdlet. How can I do it?


Solution

  • Your test for whether an exception has been thrown needs to specify the exception as a string:

    It 'Should import module ActiveDirectory' {
        {Import-Module -Name ActiveDirectory -ErrorAction Stop } | Should -Not -Throw -ExceptionType System.IO.FileNotFoundException
    }
    

    You could Mock your Import-Module as follows:

    Mock Import-Module {} -ParameterFilter {$Name -eq 'ComplexModule'}
    

    Beware that you may have issues using Import-Module successfully/legitimately in your Pester script after you've mocked it, but so long as you use it before the Mock I think you'll be OK.

    Note also that this Mock does nothing (hence the empty {}) so it effectively ensures the module is not loaded. If your tests rely on the module being loaded, you'll need to either not Mock it or find a way to load the needed commands otherwise.