Xti*_*GIS 5 powershell unit-testing mocking pester
在PowerShell中开发脚本,我需要调用外部可执行文件(.exe).目前我正在使用TDD方法开发此脚本,因此我需要模拟调用此.exe文件.
我试试这个:
Describe "Create-NewObject" {
Context "Create-Object" {
It "Runs" {
Mock '& "c:\temp\my.exe"' {return {$true}}
Create-Object| Should Be $true
}
}
}
Run Code Online (Sandbox Code Playgroud)
我收到了这个回复:
Describing Create-NewObject
Context Create-Object
[-] Runs 574ms
CommandNotFoundException: Could not find Command & "C:\temp\my.exe"
at Validate-Command, C:\Program Files\WindowsPowerShell\Modules\Pester\Functions\Mock.ps1: line 801
at Mock, C:\Program Files\WindowsPowerShell\Modules\Pester\Functions\Mock.ps1: line 168
at <ScriptBlock>, C:\T\Create-NewObject.tests.ps1: line 13
Tests completed in 574ms
Passed: 0 Failed: 1 Skipped: 0 Pending: 0 Inconclusive: 0
Run Code Online (Sandbox Code Playgroud)
有没有办法模拟这种类型的调用而不将它们封装在一个函数中?
我找到了一种模拟对这个可执行文件的调用的方法:
function Create-Object
{
$exp = '& "C:\temp\my.exe"'
Invoke-Expression -Command $exp
}
Run Code Online (Sandbox Code Playgroud)
使用模拟测试应该看起来像:
Describe "Create-NewObject" {
Context "Create-Object" {
It "Runs" {
Mock Invoke-Expression {return {$true}} -ParameterFilter {($Command -eq '& "C:\temp\my.exe"')
Create-Object| Should Be $true
}
}
}
Run Code Online (Sandbox Code Playgroud)
是的,不幸的是,从 Pester 4.8.1 开始:
C:\Windows\System32\cmd.exe)cmd),但请注意,在较旧的 Pester 版本中,仅针对显式使用.exe扩展名(例如,cmd.exe)的调用调用模拟- 请参阅此(过时)GitHub 问题您自己的解决方法是有效的,但它涉及Invoke-Expression,这很尴尬;Invoke-Expression一般应该避免
这是一个使用辅助函数的解决方法Invoke-External,它包装了外部程序的调用,并且作为一个函数,它本身可以被模拟,使用 a-ParameterFilter来过滤可执行路径:
在您的代码中,定义该Invoke-External函数,然后使用它来调用c:\temp\my.exe:
# Helper function for invoking an external utility (executable).
# The raison d'être for this function is to allow
# calls to external executables via their *full paths* to be mocked in Pester.
function Invoke-External {
param(
[Parameter(Mandatory=$true)]
[string] $LiteralPath,
[Parameter(ValueFromRemainingArguments=$true)]
$PassThruArgs
)
& $LiteralPath $PassThruArgs
}
# Call c:\temp\my.exe via invoke-External
# Note that you may pass arguments to pass the executable as usual (none here):
Invoke-External c:\temp\my.exe
Run Code Online (Sandbox Code Playgroud)
然后,c:\temp\my.exe在你的 Pester 测试中模拟调用:
Mock Invoke-External -ParameterFilter { $LiteralPath -eq 'c:\temp\my.exe' } `
-MockWith { $true }
Run Code Online (Sandbox Code Playgroud)
注意:如果您的代码中只有一个对外部可执行文件的调用,则可以省略该-ParameterFilter参数。
| 归档时间: |
|
| 查看次数: |
942 次 |
| 最近记录: |