考虑到我的powershell代码(不是函数中的,因为最后几个部分是正在运行的脚本,但是我想使用pester)检查我的脚本的一些内容,我的powershell代码WinVersion.ps1
$WindowsVersion = Get-CimInstance -ClassName Win32_Operatingsystem | select -expand Caption我的Pester剧本:
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
}
}我的写主机(在我的困扰脚本中)应该返回Microsoft Windows Server 2012 Datacenter,但是它会返回我自己的windows版本。因此它忽略了我的嘲弄。
我也尝试过没有ParameterFilter的模拟,但这也不起作用。
这就是Pester给我的结果:
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"有什么线索吗?
发布于 2022-06-03 16:39:13
有几件事:
[Microsoft.Management.Infrastructure.CimInstanc]@{ Caption = "Microsoft Windows Server 2012 Datacenter"}实际上在计算机上工作吗?如果您将其复制并粘贴到PowerShell中,您会得到该对象的实例吗?您只需使用pscustomobject在它的位置[pscustomobject]@{Caption = "Microsoft Windows Server 2012 Datacenter"}。
我可以想出两种方法来解决这个问题。
快速修复是将您的脚本点移到
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'
}
}更好的解决办法可能是重新考虑如何进行测试。在脚本中定义函数可以更容易地进行测试。
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'
}
}https://stackoverflow.com/questions/72489504
复制相似问题