1

一段时间以来,我正在慢慢学习使用 Powershell 的精彩 Pester 单元测试。我有点纠结于检查我的函数是否可以运行“如果没有向函数提供任何强制性输入”。这给了我一个红灯,并希望获得绿色测试结果并继续编码。

所以我有一个功能如下。

function Code()
{     
param(
  [parameter(Mandatory=$true)]
  [string]$SourceLocation)
return "Hello from $SourceLocation"
}

我的测试脚本执行以下检查...

$moduleName = 'Code';
Describe $moduleName {         
      Context "$Function - Returns a result " {
          It "does something useful with just $Function function name" {
            $true | Should Be $true
          }
      }

      Context "$Function - Returns with no input " {
        It "with no input returns Mandatory value expected" {
           Code | Should Throw
        }
      }

      Context "$Function - Returns some output" {
          It "with a name returns the standard phrase with that name" {
              Code "Venus" | Should Be "Hello from Venus"
          }
          It "with a name returns something that ends with name" {
              Code "Mars" | Should Match ".*Mars"
          }
      }

  } #End Describe

我从 AppVeyor 的输出显示了这个结果,其中 [+] 是绿色,[-] 是红色,这是我尽我所能避免的。

 Describing Code
    Context Code - Returns a result 
      [+] does something useful with just Code function name 16ms
    Context Code - Returns with no input 
      [-] with no input returns Mandatory value expected 49ms
        Cannot process command because of one or more missing mandatory parameters: SourceLocation.
        at <ScriptBlock>, C:\projects\code\Code.Tests.ps1: line 117
        117:            Code | Should Throw

    Context Code - Returns some output
      [+] with a name returns the standard phrase with that name 23ms
      [+] with a name returns something that ends with name 11ms

感谢您提供任何帮助,因为我希望那里有一个绿色条件,因为我不确定如何克服来自 Powershell 的某些类型的消息响应并将其转换为单元测试......

4

1 回答 1

2

根据 TessellatingHeckler 的评论,您的代码无法正常工作,因为为了进行测试,Throw您需要将Shouldcmdlet 传递给 scriptblock { }

{Code} | Should Throw

然而值得注意的是(在测试强制参数时)这在 AppVeyor 中运行良好,因为 PowerShell 在非交互式控制台 ( PowerShell.exe -noninteractive) 中运行。如果您尝试在本地运行 Pester 测试,当您收到输入提示时,您的测试似乎会被中断。

有几种方法可以解决这个问题,一种是在非交互模式下使用 PowerShell 在本地运行测试:

PowerShell.exe -noninteractive {Invoke-Pester}

另一种方法是向参数传递一个显式$null或空值(需要注意的是,您实际上可以拥有一个接受的强制字符串参数,$null并且此解决方案不一定适用于所有其他参数类型):

It "with no input returns Mandatory value expected" {
    {Code $null} | Should Throw
}

但是值得注意的是,这两种解决方案会抛出不同的异常消息,您应该进一步测试明确的消息,Throw以便在代码因其他原因失败时您的测试不会通过。例如:

使用 -noninteractive 运行

It "with no input returns Mandatory value expected" {
    {Code} | Should Throw 'Cannot process command because of one or more missing mandatory parameters: SourceLocation.'
}

传递它 $null

It "with no input returns Mandatory value expected" {
    {Code $null} | Should Throw "Cannot bind argument to parameter 'SourceLocation' because it is an empty string."
}

总之,这只是这个特定场景的一个复杂问题,因为您的参数是强制性的,并且您正在测试它是否缺失。

异常测试通常是一个简单的过程:

{ some code } | should Throw 'message'

并且在交互式和非交互式控制台中都可以正常工作。

于 2017-07-01T06:58:39.917 回答