我想知道为什么在运行此脚本时会出现以下行为。我在PowerShell ISE(v4主机)中加载了脚本并加载了Pester模块。我按F5运行脚本。
function Test-Pester {
throw("An error")
}
Describe "what happens when a function throws an error" {
Context "we test with Should Throw" {
It "Throws an error" {
{ Test-Pester } | Should Throw
}
}
Context "we test using a try-catch construct" {
$ErrorSeen = $false
try {
Test-Pester
}
catch {
$ErrorSeen = $true
}
It "is handled by try-catch" {
$ErrorSeen | Should Be $true
}
}
Context "we test using trap" {
trap {
$ErrorSeen = $true
}
$ErrorSeen = $false
Test-Pester
It "is handled by trap" {
$ErrorSeen | Should Be $true
}
}
}
然后我得到以下输出:
Describing what happens when a function throws an error
Context we test with Should Throw
[+] Throws an error 536ms
Context we test using a try-catch construct
[+] is handled by try-catch 246ms
Context we test using trap
An error
At C:\Test-Pester.ps1:2 char:7
+ throw("An error")
+ ~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (An error:String) [], RuntimeException
+ FullyQualifiedErrorId : An error
[-] is handled by trap 702ms
Expected: {True}
But was: {False}
at line: 40 in C:\Test-Pester.ps1
40: $ErrorSeen | Should Be $true
为什么trap{}
显然没有在最终测试中运行?
答案 0 :(得分:2)
以下是基于@PetSerAl和@Eris的评论/建议答案的问题的两种解决方案。我也阅读并赞赏这个问题的答案:
Why are variable assignments within a Trap block not visible outside it?
虽然可以在陷阱中读取脚本中设置的变量,但是在陷阱中执行的任何操作都发生在该变量的副本中,即仅在陷阱本地的范围内。在此解决方案中,我们将引用评估为$ErrorSeen
,以便在设置变量的值时,实际上设置父范围中存在的变量的值。
向陷阱添加continue
会抑制ErrorRecord的详细信息,从而清除测试的输出。
Describe "what happens when a function throws an error" {
Context "we test using trap" {
$ErrorSeen = $false
trap {
Write-Warning "Error trapped"
([Ref]$ErrorSeen).Value = $true
continue
}
Test-Pester
It "is handled by trap" {
$ErrorSeen | Should Be $true
}
}
}
与第一个解决方案一样,问题可以通过在$ErrorSeen
变量(1)首次创建时明确设置范围来解决,(2)在{{1}中使用时}。我在这里使用了脚本范围,但Global似乎也有效。
同样的原则适用于此:我们需要避免陷阱中变量的更改仅发生在变量的本地副本上的问题。
trap {}
答案 1 :(得分:1)
根据this blog,您需要告诉陷阱对控制流程做些什么:
您注意到的事情是,当您以脚本形式运行时,您将收到错误消息和红色PowerShell错误消息。
. 'C:\Scripts\test.ps1'
Something terrible happened!
Attempted to divide by zero.
At C:\Scripts\test.ps1:2 Char:3
+ 1/ <<<< null
这是因为你的Trap并没有真正处理异常。要处理异常,您需要将“Continue”语句添加到陷阱中:
trap { 'Something terrible happened!'; continue }
1/$null
现在,陷阱按预期工作。它执行您在陷阱脚本块中指定的任何内容,并且PowerShell不再能够查看异常。您不再收到红色错误消息。