使用Pester测试Get-EvenNumbers函数出现返回类型错误的问题
问题背景
我正在学习Pester,使用ChatGPT生成的Get-EvenNumbers函数及对应的Pester测试代码,执行测试时出现类型不匹配错误,但我认为函数返回的应该是[int]数组,想知道错误原因。
Get-EvenNumbers函数代码
function Get-EvenNumbers { param( [Parameter(Mandatory=$true)] [int]$start, [Parameter(Mandatory=$true)] [int]$end ) $evenNumbers = @() for ($i = $start; $i -le $end; $i++) { if ($i % 2 -eq 0) { $evenNumbers += $i } } return $evenNumbers }
Pester测试代码
Describe "Get-EvenNumbers" { Context "When the input range is from 1 to 10" { $start = 1 $end = 10 It "Returns an array of even numbers" { $result = Get-EvenNumbers -Start $start -End $end $result | Should -BeOfType "System.Array" $result | Should -Not -BeNullOrEmpty $result | Should -ContainOnly (2, 4, 6, 8, 10) } } Context "When the input range is from 2 to 9" { $start = 2 $end = 9 It "Returns an array of even numbers" { $result = Get-EvenNumbers -Start $start -End $end $result | Should -BeOfType "System.Array" $result | Should -Not -BeNullOrEmpty $result | Should -ContainOnly (2, 4, 6, 8) } } }
测试错误信息
[-] Get-EvenNumbers.When the input range is from 1 to 10.Returns an array of even numbers 10ms (8ms|1ms)
Expected the value to have type [array] or any of its subtypes, but got 2 with type [int].
at $result | Should -BeOfType "System.Array", C:\Users\Pester\Get-EvenNumbers.Tests.ps1:8
at , C:\Users\Pester\Get-EvenNumbers.Tests.ps1:8
[-] Get-EvenNumbers.When the input range is from 2 to 9.Returns an array of even numbers 13ms (9ms|4ms)
Expected the value to have type [array] or any of its subtypes, but got 2 with type [int].
at $result | Should -BeOfType "System.Array", C:\Users\Pester\Get-EvenNumbers.Tests.ps1:20
at , C:\Users\Pester\Get-EvenNumbers.Tests.ps1:20
Tests completed in 177ms
Tests Passed: 0, Failed: 2, Skipped: 0 NotRun: 0
错误原因分析
这是PowerShell的管道遍历特性导致的:
- 当你把数组通过管道传给
Should -BeOfType时,PowerShell会自动遍历数组中的每个元素,对单个元素进行类型检查,而不是检查整个变量的数组类型。错误信息里提到的“got 2 with type [int]”,就是因为它拿数组的第一个元素(2)去和System.Array类型做对比,自然不匹配。
修正方案
有两种简单的解决方式:
- 直接传递变量参数:不使用管道,而是通过参数传递整个变量,让Pester检查变量的整体类型:
# 原代码 $result | Should -BeOfType "System.Array" # 修改后 Should -BeOfType -ActualValue $result -ExpectedType "System.Array" - 使用更准确的类型断言:可以直接检查是否为数组类型,或者匹配具体的[int[]]类型:
# 检查是否为数组 $result | Should -IsArray # 或者检查具体的整数数组类型 $result | Should -BeOfType [int[]]
调整后就能正确验证函数返回值是数组类型,测试也能通过。
内容的提问来源于stack exchange,提问作者Purclot

