Пустой список в Pester Mock создан из замыкания

Почему следующий код:

  function CreateExecutedCommandsLogger(){
     param(
        [System.Collections.Generic.List[System.String]]$cmdLog
     )
     "WWWWW=>{0}" -f $cmdLog | Write-Host
     return{
        param(
           [parameter(valuefrompipeline)]$command
        )
        "XXXXX=>{0}" -f $command | Write-Host
        "YYYYY=>{0}" -f $cmdLog | Write-Host
        $cmdLog.Add($command)
     }.GetNewClosure()
  }

  $executedCommands = New-Object System.Collections.Generic.List[System.String]
  Mock ExecuteSqlCommand (CreateExecutedCommandsLogger $executedCommands)

Результат в ошибке:

  RuntimeException: You cannot call a method on a null-valued expression.
  at <ScriptBlock>, <No file>: line 7
  at <ScriptBlock>, C:\Users\notme\Documents\WindowsPowerShell\Modules\Pester\Functions\Mock.ps1: line 1018
  at ExecuteBlock, C:\Users\notme\Documents\WindowsPowerShell\Modules\Pester\Functions\Mock.ps1: line 1022
  at Invoke-Mock, C:\Users\notme\Documents\WindowsPowerShell\Modules\Pester\Functions\Mock.ps1: line 868
  at <ScriptBlock><Process>, <No file>: line 53

Для справки вывод трассировки дает:

WWWWW=>System.Collections.Generic.List`1[System.String]
XXXXX=>C:\dummy\command.exe -S "blah" -d "blahblah" -i "something.sql"
YYYYY=>

Когда я использую следующее, это работает:

  $dummyMock = (CreateExecutedCommandsLogger $executedCommands)
  &$dummyMock "blah"

Я предполагаю, что это как-то связано с тем, как выполняется блок скриптов в макете?

1 ответ

Решение

Как вы можете видеть из источника (Get-Command Mock).ScriptBlockесть одна строка где $MockWith параметр используется:

$mockWithCopy = [scriptblock]::Create($MockWith.ToString())

Чтобы, $MockWith фактически это строка, и любое закрытие игнорируется. Скорее всего это сделано потому, что на следующей строке только что созданный скрипт-блок $mockWithCopy ограниченный некоторым состоянием сеанса, таким образом, вы теряете свое закрытие в любом случае:

Set-ScriptBlockScope -ScriptBlock $mockWithCopy -SessionState $contextInfo.Session

Сначала Пестер делает личную копию блока скрипта, чтобы не повлиять на переданный экземпляр.

Другие вопросы по тегам