Pester测试PowerShell工作流InlineScript调用失败,寻求解决方案
关于Pester测试PowerShell工作流InlineScript块内调用的问题
我使用Invoke-Pester执行测试时,TestFunction函数的测试可以正常通过,但TestWorkflow工作流的测试失败,请问有没有方法让测试识别InlineScript块内的调用?
测试代码
BeforeAll { function TestFunction { Write-Host "Executing function" Get-Host } workflow TestWorkflow { InlineScript { Write-Host "Executing inlinescript" Get-Host } } } Describe "Test-Workflow" { BeforeAll { Mock Get-Host { "Mocked Get-Host" } } Context 'test' { It 'workflow' { TestWorkflow Should -Invoke -Command Get-Host -Exactly 1 } It 'function' { TestFunction Should -Invoke -Command Get-Host -Exactly 1 } } }
测试结果
[-] Test-Workflow.test.workflow 1.53s (1.53s|4ms) 预期Get-Host被调用恰好1次,但实际被调用0次 at Should -Invoke -Command Get-Host -Exactly 1, C:\Test-Workflow.Tests.ps1:25 at <ScriptBlock>, C:\Test-Workflow.Tests.ps1:25 Executing function Tests completed in 1.97s Tests Passed: 1, Failed: 1, Skipped: 0 NotRun: 0
问题原因
PowerShell工作流的InlineScript块是在独立的子进程中执行的,而Pester的Mock功能完全基于当前PowerShell会话,无法跨进程追踪命令调用。你在主会话中定义的Get-Host Mock,对InlineScript所在的子进程完全无效,自然检测不到调用记录。
解决方案
方案1:弃用工作流(推荐)
PowerShell工作流已被官方弃用(从PowerShell 5.1起停止更新,后续版本不再支持),建议改用普通函数、Start-Job或Runspace实现异步/并行逻辑,这样Pester的Mock可以正常追踪调用。
方案2:调整测试逻辑适配InlineScript
如果必须保留工作流,只能放弃Should -Invoke的调用次数验证,转而通过验证工作流的输出结果确认逻辑执行,具体修改如下:
修改工作流让InlineScript返回执行结果,同时在子进程内注入Mock逻辑:
BeforeAll { function TestFunction { Write-Host "Executing function" Get-Host } workflow TestWorkflow { InlineScript { Write-Host "Executing inlinescript" # 在子进程内定义Mock版本的Get-Host function Get-Host { return "Mocked Get-Host" } # 返回执行结果给主进程 return Get-Host } } } Describe "Test-Workflow" { Context 'test' { It 'workflow' { $result = TestWorkflow # 验证返回结果是否符合Mock预期 $result | Should -Be "Mocked Get-Host" } It 'function' { Mock Get-Host { "Mocked Get-Host" } TestFunction Should -Invoke -Command Get-Host -Exactly 1 } } }
注意:这种方式无法用Should -Invoke统计调用次数,因为子进程的调用无法被主会话的Pester追踪,只能通过结果反推逻辑是否执行。
内容的提问来源于stack exchange,提问作者xenull
相关产品推荐
相关产品推荐

