【问题标题】:Why Pester does not mock a cmdlet with two parameters?为什么 Pester 不模拟带有两个参数的 cmdlet?
【发布时间】:2016-02-15 21:32:22
【问题描述】:

我正在尝试进行一些 Pester 测试,但出现奇怪的错误“找不到位置参数”(对于私有 Python cmdlet),这是 Pester 的限制还是我下面的代码有问题?

TestModule.psm1代码:

#public function:
Function Create-Db 
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory, ValueFromPipeline)]
        [string]$database
    )

    Python 'Files\create_db.py' '--DBMS=SQLSERVER -d $database'
}

#private (not exported) function:
Function Python
{
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory, Position=1)]
        [string]$scriptFile,
        [Parameter(Position=2)]
        [string]$args
    )

    $python ='C:\Python27\python.exe'
    Push-Location $PSScriptRoot

    $python = Start-Process -FilePath $python -ArgumentList @($scriptFile,$args) -Wait -NoNewWindow -PassThru
    if($python.ExitCode -ne 0)
    {
        throw "Python script", $scriptFile, "failed"
    }

    Pop-Location
}

函数的纠缠代码:

$scriptDirectory = (Split-Path -Parent $MyInvocation.MyCommand.Path) -replace "Test$"
Import-Module $scriptDirectory\TestModule.psm1 -Force

Describe "Create-Db test" {
    Context "Create database" {

        Mock -ModuleName TestModule Python -Verifiable { return; }
        Create-Db -database "test_database"

        It "Python has been called" {
            Assert-VerifiableMocks
        }
    }
}

当我执行测试代码时出现此错误:

描述 Create-Db 测试
   上下文 创建数据库
    [-] 上下文块 1.35 秒发生错误
      ParameterBindingException:找不到接受参数“--DBMS SqlServer -d test_database”的位置参数。
      在 Test-ParameterFilter,C:\Program Files\WindowsPowerShell\Modules\Pester\3.3.14\Functions\Mock.ps1:第 1086 行

【问题讨论】:

    标签: powershell pester


    【解决方案1】:

    $args 是一个自动变量,它包含非高级函数的所有非绑定参数。佩斯特是这样解释的。当调用模拟命令时,Pester 捕获 $PSBoundParameters$args 作为传递参数的指示。后来 Pester splat 将捕获的值传递给参数过滤例程。

    您代码中的“错误” 是您将$args 用作函数的常规参数,这让Pester 感到困惑。当嘲笑Python 调用时,Pester 看到:

    $PSBoundParameters = @{
        scriptFile = 'Files\create_db.py'
        args = '--DBMS=SQLSERVER -d $database'
    }
    $args = '--DBMS=SQLSERVER -d $database'
    

    稍后 Pester 调用参数过滤脚本,具有等效的此类参数:

    -scriptFile: 'Files\create_db.py' -args: '--DBMS=SQLSERVER -d $database' '--DBMS=SQLSERVER -d $database'
    

    由于参数过滤脚本没有定义任何参数,可以接受位置参数'--DBMS=SQLSERVER -d $database',所以你得到了ParameterBindingException

    您可能可以将这种行为称为 Pester 中的错误。由于高级函数不会填充$args 自动变量,因此不应首先捕获它。 Pester 已经有了不从父作用域捕获$args 的保护,它只需要在模拟高级功能或cmdlet 时不捕获$args 的附加保护。

    但是你真的不应该使用$args 作为普通参数。您最好将参数名称更改为Arguments 并使用Args 作为别名:

    [Parameter(Position=2)]
    [Alias('Args')]
    [string]$Arguments
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-07
    • 2012-02-08
    • 1970-01-01
    相关资源
    最近更新 更多