如何用Pester验证Mock的Invoke-RestMethod被传入正确参数?
解决Pester测试中验证Invoke-RestMethod哈希表参数的问题
先打消你的顾虑:Mock不会触发真实调用
Pester的Mock命令默认会完全拦截目标命令的所有调用,哪怕ParameterFilter不匹配,也只会返回你定义的Mock脚本块结果(比如空),绝对不会执行真实的Invoke-RestMethod。只要你在测试块开头正确定义了Mock,就不用担心真实API被调用。
核心方法:用ParameterFilter验证哈希表的键值对
因为哈希表是引用类型,直接用-eq比较是否相等是行不通的,但你可以在ParameterFilter里直接访问Invoke-RestMethod的参数(比如$Headers、$Body、$Query),然后逐一检查里面的键值对是否符合预期。
示例1:验证TechnicianKey在Header、InputData在Body的场景
Describe "Invoke-GetRequest Tests" { # 提前Mock掉Invoke-RestMethod,确保所有调用都被拦截 Mock Invoke-RestMethod {} It "puts TechnicianKey in Headers and InputData in Body when specified" { # 定义测试用的参数值 $testTechKey = "ABC-123-XYZ" $testInputData = @{ UserId = 999 Action = "GetDetails" } # 调用被测函数 Invoke-GetRequest -SendTechnicianKeyIn Header ` -TechnicianKey $testTechKey ` -SendInputDataIn Body ` -InputData $testInputData # 验证Mock被正确调用,且参数符合预期 Should -Invoke Invoke-RestMethod -Exactly 1 -ParameterFilter { # 检查Headers哈希表是否包含指定键值 $Headers['TechnicianKey'] -eq $testTechKey -and # 检查Body里的每个属性是否匹配 $Body.UserId -eq $testInputData.UserId -and $Body.Action -eq $testInputData.Action } } }
示例2:验证InputData通过QueryString传递的场景
It "puts InputData in Query parameters when SendInputDataIn is 'QueryString'" { $testQueryData = @{SearchTerm="powershell"; Page=2} Invoke-GetRequest -SendInputDataIn QueryString -InputData $testQueryData Should -Invoke Invoke-RestMethod -Exactly 1 -ParameterFilter { # Query参数在Invoke-RestMethod里对应-Query参数(哈希表类型) $Query.SearchTerm -eq $testQueryData.SearchTerm -and $Query.Page -eq $testQueryData.Page } }
进阶:用辅助函数简化复杂哈希表的验证
如果需要频繁验证结构复杂的哈希表,可以写一个小辅助函数来对比键值对,让测试代码更简洁:
# 在测试脚本中定义辅助函数 function Test-HashContentMatches { param( [hashtable]$Actual, [hashtable]$Expected ) # 检查所有预期的键是否存在且值匹配 foreach ($key in $Expected.Keys) { if (-not $Actual.ContainsKey($key) -or $Actual[$key] -ne $Expected[$key]) { return $false } } # 可选:如果需要严格匹配(不允许额外键),加上下面这行 # return $Actual.Count -eq $Expected.Count return $true } # 在测试中使用 It "uses correct Headers and Query parameters" { $expectedHeaders = @{TechnicianKey="test-key"} $expectedQuery = @{Limit=10; Sort="asc"} Invoke-GetRequest -SendTechnicianKeyIn Header -TechnicianKey $expectedHeaders.TechnicianKey ` -SendInputDataIn QueryString -InputData $expectedQuery Should -Invoke Invoke-RestMethod -Exactly 1 -ParameterFilter { Test-HashContentMatches -Actual $Headers -Expected $expectedHeaders -and Test-HashContentMatches -Actual $Query -Expected $expectedQuery } }
关键注意事项
- 永远不要直接用
$Headers -eq @{...}比较哈希表,这只会检查两个变量是否指向同一个对象,而不是内容是否一致。 - 用
-Exactly 1指定调用次数,避免函数多次调用Invoke-RestMethod时出现误判。 - 确保Mock定义在
Describe或Context块内,作用域覆盖所有需要测试的It块。
内容的提问来源于stack exchange,提问作者Ninja
相关产品推荐
相关产品推荐

