我正在试图弄清楚如何对缺少的参数进行Pester测试:
查找-Waldo.Tests.ps1
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
Describe 'Mandatory paramters' {
it 'ComputerName' {
{
$Params = @{
#ComputerName = 'MyPc'
ScriptName = 'Test'
}
. "$here\$sut" @Params
} | Should throw
}
}
查找-Waldo.ps1
Param (
[Parameter(Mandatory)]
[String]$ComputerName,
[String]$ScriptName
)
Function Find-Waldo {
[CmdletBinding()]
Param (
[String]$FilePath
)
'Do something'
}
每次尝试assert
结果或只是运行测试时,它都会提示我输入ComputerName
参数而不是测试失败。
我错过了一些非常明显的东西吗?有没有办法测试是否存在强制参数?
答案 0 :(得分:4)
根据Mathias的评论,您无法真正测试是否缺少Mandatory参数,因为PowerShell会提示它而不是抛出错误。根据{{3}},您可以使用Get-Command
来测试脚本中的Mandatory参数设置:
((Get-Command "$here\$sut").Parameters['ComputerName'].Attributes.Mandatory | Should Be $true
另一种选择是在此实例中不使用强制参数,而是使用一个脚本块来执行Throw
作为参数的默认值:
Param (
[String]$ComputerName = $(Throw '-ComputerName is required'),
[String]$ScriptName
)
如果脚本总是用作自动化过程的一部分(而不是通过用户执行),那么这可能是首选,因为它允许您控制/捕获其行为并避免它在执行期间卡住。然后,您可以按照最初的建议测试脚本:
Describe 'Mandatory paramters' {
it 'ComputerName' {
{
$Params = @{
#ComputerName = 'MyPc'
ScriptName = 'Test'
}
. "$here\$sut" @Params
} | Should throw '-ComputerName is required'
}
}
答案 1 :(得分:1)
尽管接受的答案表明这是不可能的,但实际上是可能的。这是我为解决此问题而开发的解决方案。
It 'Should fail when no priority is specified, for a valid process name' {
{
$ScriptBlock = {
Import-Module -Name $args[0]
Set-ProcessPriority -Name System
}
Start-Job -ScriptBlock $ScriptBlock -ArgumentList $HOME/git/ProcessPriority/src/ProcessPriority | Wait-Job | Receive-Job
} | Should -Throw
}
从以上示例中您会注意到:
?被测试的代码已包装在PowerShell ScriptBlock
?我们调用一个包含测试代码的PowerShell后台作业
?我们等待后台作业完成,然后接收结果
?如果运行Get-Job
命令,您会注意到有一个工作处于Blocked
状态
后台作业引发的异常类似于以下内容:
Wait-Job cmdlet无法完成工作,因为阻止了一个或多个作业等待用户交互。使用Receive-Job cmdlet处理交互式作业输出,然后重试。
您会注意到,我将文件系统路径硬编码为模块。我不确定如何将其作为Pester为我们调用的“外部” ScriptBlock
的参数。也许有人对如何完成最后的难题提出了建议。
PowerShell后台作业的唯一有趣之处在于,您实际上可以恢复处于Blocked
状态的作业,即使它抛出了先前的异常,它也会提示您输入。