2016-02-15 2 views
1

Я пытаюсь провести некоторое тестирование Pester, и я получаю странную ошибку «Не найден позиционный параметр» (для частного командлета Python), это ограничение Pester или что-то не так с моим кодом ниже?Почему 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 
} 

Pester код функция:

$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 
     } 
    } 
} 

Когда я выполнить тестовый код, я получаю эту ошибку:

Describing Create-Db test 
    Context Create database 
    [-] Error occurred in Context block 1.35s 
     ParameterBindingException: A positional parameter cannot be found that accepts argument '--DBMS SqlServer -d test_database'. 
     at Test-ParameterFilter, C:\Program Files\WindowsPowerShell\Modules\Pester\3.3.14\Functions\Mock.ps1: line 1086

ответ

4

$args является автоматическим переменным который содержит все несвязанные аргументы для неусовершенствованных функций. И это интерпретируется Пестером как таковым. Когда команда mocked вызывается, 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 из родительской области, ему просто нужна дополнительная защита, чтобы не захватывать $args при издевательской расширенной функции или командлете.

Но вы действительно не должны использовать $args как обычный параметр. Лучше изменить параметр имя Arguments и использовать Args в качестве псевдонима:

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

По крайней мере, до понадоедайте 3.3.14, вы должны избегать называть имена параметров SUT, которые сталкиваются с [автоматическими именами переменных] (https: // TechNet .microsoft.com/EN-US/библиотека/hh847768.aspx). [Об этом уже было какое-то недоумение] (https://github.com/pester/Pester/issues/303), и вывод на данный момент кажется [«люди должны быть осторожны, чтобы не перезаписывать автоматические переменные»] (https://github.com/pester/Pester/pull/437#issue-121484891). – alx9r

Смежные вопросы