Search code examples
powershellpester

Is there any way to mock $PSVersionTable variable of powershell in pester


Is there any way to mock the $PSVersionTable variable of PowerShell with Pester?

Here is my code:

Testcase.ps1:

trap [Exception] {
    write-error $("TRAPPED: " + $_)
    exit 1
    }

function Check_Powershell_Version

{
    $PSVersion = $PSVersionTable.PSVersion.Major

if ($PSVersion -lt 3){
    echo "Current version is not compatible. Please upgrade powershell"
    }
}

Testcase.Tests.ps1:

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"

Describe "SRP testing" {
    It "Check Powershell Version" {

    Mock $PSVersionTable {
                return{ @{ PSVersion = [Version]'1.0.0' } }
    }

    Check_Powershell_Version

    Assert-MockCalled $PSVersionTable -Times 1        
    }
    }

I want to mock the $PSVersionTable variable so that I can check that it has been called.


Solution

  • You can't Mock a variable. You could however wrap what that variable returns as a function and then mock that function. For example:

    function Get-PSVersion { $PSVersionTable }
    
    function Check_Powershell_Version
    {
        $PSVersion = (Get-PSVersion).PSVersion.Major
    
        if ($PSVersion -lt 3){
            echo 'Current version is not compatible. Please upgrade powershell'
        }
    }
    
    Describe 'SRP testing' {
        It 'Check Powershell Version' {
    
            Mock Get-PSVersion {
                [pscustomobject]@{ PSVersion = [Version]'1.0.0' }
            }
    
            Mock echo { }
    
            Check_Powershell_Version
    
            Assert-MockCalled Get-PSVersion -Times 1
            Assert-MockCalled echo -Times 1
        }
    }
    

    I have declared a function named Get-PSVersion which is just used to return $PSVersionTable. Then in the Mock we can substitute its usual result with a pscustomobject that has a PSVersion property and a specified version. I have also added a Mock for echo (beware this is an alias of Write-Output) so that your Pester script also checks that this cmdlet is invoked (which we expect it to because we've fixed the version to be less than 3).

    Also FYI, you can use a #Requires -Version 3.0 statement at the top of your module or scripts to get the same functionality that your Check_PowerShell_Version function is providing here.