我正在慢慢地学习使用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的某些类型的消息响应并将其转换为单元测试......
答案 0 :(得分:2)
根据TessellatingHeckler的评论,您的代码无效,因为为了测试Throw
,您需要将Should
cmdlet传递给一个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
的显式消息,以便在代码因某些其他原因失败时您的测试无法通过。 E.g:
使用-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'
在交互式和非交互式控制台中都可以正常工作。