Reputation: 53
Given my powershell code (not in a function, as the last few parts are the script running, but i want to check some stuff for my script, using pester) My powershell code WinVersion.ps1
$WindowsVersion = Get-CimInstance -ClassName Win32_Operatingsystem | select -expand Caption
My Pester script:
BeforeAll {
. $PSCommandPath.Replace('.Tests.ps1', '.ps1')
}
Describe "Test Server 2012" {
It "Given Server 2012, return correct data" {
Mock -CommandName Get-CimInstance -ParameterFilter {$ClassName -eq "Win32_Operatingsystem"} -MockWith {
Write-Host "CIM"
return [Microsoft.Management.Infrastructure.CimInstanc]@{
Caption = "Microsoft Windows Server 2012 Datacenter"
}
}
write-host $WindowsVersion
}
}
My Write-host (in my pester script) should return Microsoft Windows Server 2012 Datacenter
but it returns my own windows version. It thus ignores my mock.
I also tried the mock without the ParameterFilter, but that also didn't work.
This is the result that Pester gives me:
Starting discovery in 1 files.
Discovery found 2 tests in 82ms.
Running tests.
[-] Test Server 2012.Given Server 2012, return correct data 46ms (45ms|1ms)
Expected strings to be the same, but they were different.
Expected length: 40
Actual length: 31
Strings differ at index 18.
Expected: 'Microsoft Windows Server 2012 Datacenter'
But was: 'Microsoft Windows 11 Enterprise'
------------------^
at $WindowsVersion | Should -Be "Microsoft Windows Server 2012 Datacenter"
Any clue why?
Upvotes: 2
Views: 304
Reputation: 5114
A few things:
[Microsoft.Management.Infrastructure.CimInstanc]@{ Caption = "Microsoft Windows Server 2012 Datacenter"}
actually work on your computer? If you copy and paste that into PowerShell do you get an instance of that object back? You could just use a pscustomobject in its place [pscustomobject]@{Caption = "Microsoft Windows Server 2012 Datacenter"}
There are two options I can think of to resolve this.
Quick fix is to just move where you are dot sourcing your script at
Describe 'Test Server 2012' {
BeforeAll {
Mock -CommandName Get-CimInstance -ParameterFilter { $ClassName -eq 'Win32_Operatingsystem' } -MockWith {
[pscustomobject]@{Caption = 'Microsoft Windows Server 2012 Datacenter' }
}
# source the script here after mock is defined but before tests are run
. $PSScriptRoot\somescript.ps1
}
It 'Given Server 2012, return correct data' {
$WindowsVersion | Should -Be 'Microsoft Windows Server 2012 Datacenter'
}
}
A better fix might be to reconsider how to go about testing. Defining functions in your script allows you to test more easily
BeforeAll {
# Everything in this block executes before the tests are set up and ran
# This command dot sources the script we are testing
# . $PSCommandPath.Replace('.Tests.ps1', '.ps1')
# Defining functions that can be run in our tests.
# This could instead be defined in the script that we are testing
function Test-Mock {
Get-CimInstance -ClassName Win32_Operatingsystem | Select-Object -ExpandProperty Caption
}
function Test-UnaffectedByMock{
Get-CimInstance -ClassName Win32_Volume | Select-Object -ExpandProperty Caption
}
}
Describe 'Test Server 2012' {
BeforeAll {
Mock -CommandName Get-CimInstance -ParameterFilter { $ClassName -eq 'Win32_Operatingsystem' } -MockWith {
[pscustomobject]@{Caption = 'Microsoft Windows Server 2012 Datacenter' }
}
}
It 'Given Server 2012, return correct data' {
Test-Mock | Should -Be 'Microsoft Windows Server 2012 Datacenter'
}
It 'Supplying different ClassName should not run mock' {
Test-UnaffectedByMock | Should -Not -Be 'Microsoft Windows Server 2012 Datacenter'
}
}
Upvotes: 0