【问题标题】:Pester doesn't catch the thrown errorPester 没有捕捉到抛出的错误
【发布时间】:2018-03-08 19:58:40
【问题描述】:

当我运行以下纠缠测试时,我希望它能够捕获预期的错误,但它没有。但是当我使用不同的函数和不同的 throw 语句运行测试时,它可以工作。

Pester 测试:

Describe "Remove-GenericCredential Function Tests" {
  $InternetOrNetworkAddress = 'https://PesterTestUser@PesterTestURl.com'

  Context "Test:  Remove-GenericCredential -InternetOrNetworkAddress '$InternetOrNetworkAddress' (Credential does not exist)" {
  It "This Command threw an error.  The credential does not exist." { { (Remove-GenericCredential -InternetOrNetworkAddress $InternetOrNetworkAddress -Confirm:$false) } | should throw "Remove-GenericCredential : Credential $InternetOrNetworkAddress not found" }
  }
}

未被捕获的错误:

Remove-GenericCredential : Credential https://PesterTestUser@PesterTestURl.com not found

At C:\Users\klocke7\Documents\WindowsPowerShell\Modules\Ford_CredentialManager\Tests\Remove-GenericCredential.Tests.ps1:30 char:76
+ ... xist." { { (Remove-GenericCredential -InternetOrNetworkAddress $Inter ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Write-Error], WriteErrorException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Remove-GenericCredential

      [-] This Command threw an error.  The credential does not exist. 44ms
        Expected: the expression to throw an exception with message {Remove-GenericCredential : Credential https://PesterTestUser@PesterTestURl.com not found}, an exception was not raised, message was {}
            from C:\Users\klocke7\Documents\WindowsPowerShell\Modules\Ford_CredentialManager\Tests\New-GitHubCredential.Tests.ps1:59 char:176
            + ... e $UserName -Token 'NotAGitHubTokenSpecialCharacters!@#$%^&*') } | sh ...
            +                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        at <ScriptBlock>, C:\Users\klocke7\Documents\WindowsPowerShell\Modules\Ford_CredentialManager\Tests\Remove-GenericCredential.Tests.ps1: line 30
        30:     It "This Command threw an error.  The credential does not exist." { { (Remove-GenericCredential -InternetOrNetworkAddress $InternetOrNetworkAddress -Confirm:$false) } | should throw 'Remove-GenericCredential : Credential https://PesterTestUser@PesterTestURl.com not found' }

【问题讨论】:

  • 你能告诉我们Remove-GenericCredential或者至少是引发原始错误的代码吗?
  • 写入错误-消息“未找到凭据 $InternetOrNetworkAddress”-Category ObjectNotFound
  • 不应该是.... | Should -Throw而不是.... | Should Throw吗?并且, throw 后面应该跟在 throw 语句中使用的字符串,例如 { throw "mud" } |应该 - 扔“泥”会过去。否则,请仔细检查您认为该函数在做什么,它在做什么。
  • Should Throw 和 Should -Throw 产生相同的错误。我的抛出字符串似乎与 write-error 语句抛出的字符串相同。

标签: powershell pester


【解决方案1】:

根据另一个答案,该函数抛出一个non-terminating error,因此它不被认为与Should Throw 的测试相匹配,Should Throw 正在检查终止错误。

有两种方法可以解决这个问题:

  1. 您可以通过将Write-Error 更改为Throw 来更改它,使其引发终止错误。
  2. 您可以更改测试以强制函数抛出终止错误,即使在调用它时使用-ErrorAction Stop(我可以看到您正在使用-Confirm,我假设您已经使用过[cmdletbinding()]在函数中添加-ErrorAction等常用参数。

这是第二种解决方案的示例(我已经在顶部模拟了该函数,以便我可以对此进行测试,但您无需将其包含在测试脚本中):

Function Remove-GenericCredential {
    [cmdletbinding(supportsshouldprocess)]
    Param(
        $InternetOrNetworkAddress
    )

    Write-Error "Remove-GenericCredential : Credential $InternetOrNetworkAddress not found"
}

Describe "Remove-GenericCredential Function Tests" {
    $InternetOrNetworkAddress = 'https://PesterTestUser@PesterTestURl.com'

    Context "Test:  Remove-GenericCredential -InternetOrNetworkAddress '$InternetOrNetworkAddress' (Credential does not exist)" {
    It "This Command threw an error.  The credential does not exist." { 
        { (Remove-GenericCredential -InternetOrNetworkAddress $InternetOrNetworkAddress -Confirm:$false -ErrorAction Stop) } | should throw "Remove-GenericCredential : Credential $InternetOrNetworkAddress not found" }
    }
}

来自help Write-Error

Write-Error cmdlet 声明了一个非终止错误。默认, 错误在错误流中发送到主机程序以进行处理 与输出一起显示。

要写入非终止错误,请输入错误消息字符串、ErrorRecord 对象或 Exception 对象。使用 Write-Error 的其他参数填充错误记录。

非终止错误将错误写入错误流,但它们不会停止命令处理。如果在输入项集合中的一项上声明了非终止错误,则该命令将继续处理集合中的其他项。

要声明终止错误,请使用 Throw 关键字。有关详细信息,请参阅 about_Throw (http://go.microsoft.com/fwlink/?LinkID=145153)。

【讨论】:

    【解决方案2】:

    这可能是因为 cmdlet 引发了非终止错误,因为 Pester 仅断言终止错误。在这种情况下,需要按如下方式重写测试(根据您的示例使用旧的 Pester v3 语法):

    It "Test a non-terminating error gets thrown" {
      $errorThrown = $false;
      try
      {
        Invoke-CmdletThatThrowsNonTerminatingError -ErrorAction Stop
      }
      catch
      {
        $errorThrown = $true
      }
      $errorThrown | Should Be $true
    }
    

    在catch块中,您还可以在$_ ob 上获取异常详细信息,例如消息或异常类型

    【讨论】:

      猜你喜欢
      • 2014-03-02
      • 2012-03-31
      • 1970-01-01
      • 1970-01-01
      • 2015-08-27
      • 1970-01-01
      • 1970-01-01
      • 2015-10-22
      • 2015-03-12
      相关资源
      最近更新 更多