首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Pester不使用陷阱捕捉错误

为什么Pester不使用陷阱捕捉错误
EN

Stack Overflow用户
提问于 2016-04-15 16:24:28
回答 2查看 1.2K关注 0票数 2

我想知道为什么在运行此脚本时会出现以下行为。我在PowerShell ISE (v4主机)中加载了脚本,并加载了Pester模块。我通过按F5来运行脚本。

代码语言:javascript
复制
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
    }
  }
}

然后得到以下输出:

代码语言:javascript
复制
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{}显然没有在最终测试中运行?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-04-16 20:28:00

以下是基于@PetSerAl和@Eris的评论/建议答案的两种解决方案。我也阅读并赞赏对这一问题的答复:

为什么Trap块中的变量赋值在其外部不可见?

解决方案1

虽然脚本中设置的变量可以在陷阱中读取,但是无论您在陷阱中做什么,都会发生在该变量的副本上,即仅在陷阱的本地作用域中。在这个解决方案中,我们评估了对$ErrorSeen的引用,这样当我们设置变量的值时,我们实际上是在设置父作用域中存在的变量的值。

向陷阱中添加一个continue会抑制ErrorRecord细节,从而清理测试的输出。

代码语言:javascript
复制
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
    }
  }
}

解决方案2

按照与第一个解决方案相同的思路,问题可以通过显式设置$ErrorSeen变量的作用域(1)在第一次创建时以及(2)在trap {}中使用来解决。我在这里使用了脚本范围,但Global似乎也能工作。

同样的原则也适用于这里:我们需要避免这样的问题:在陷阱中对变量的更改只发生在变量的本地副本上。

代码语言:javascript
复制
Describe "what happens when a function throws an error" {
  Context "we test using trap" {

    $Script:ErrorSeen = $false

    trap {
      Write-Warning "Error trapped"
      $Script:ErrorSeen = $true
      continue
    }

    Test-Pester

    It "is handled by trap" {
      $ErrorSeen | Should Be $true
    }
  }
}
票数 2
EN

Stack Overflow用户

发布于 2016-04-15 17:35:22

根据这个博客,您需要告诉陷阱对控制流做些什么:

那个..。您注意到,当您作为脚本运行此脚本时,您将同时收到错误消息和红色PowerShell错误消息。

代码语言:javascript
复制
. 'C:\Scripts\test.ps1'
Something terrible happened!
Attempted to divide by zero.
At C:\Scripts\test.ps1:2 Char:3
+ 1/ <<<< null

这是因为你的陷阱没有真正处理异常。要处理异常,需要将“继续”语句添加到陷阱中:

代码语言:javascript
复制
trap { 'Something terrible happened!'; continue }
1/$null

现在,陷阱如预期的那样起作用。它执行您在陷阱脚本块中指定的任何操作,PowerShell将不再看到异常。您将不再收到红色错误消息。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36652319

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档