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.
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.