2016-05-17 4 views
2

У меня есть файл PowerShell .ps1, который содержит функции в верхней части скрипта, за которыми следуют различные команды, вызывающие эти функции. Я использую Pester для тестирования моего файла сценария.Макет функции в скрипте ps1

Как мне высмеять функцию, которая находится в моем сценарии PowerShell .ps1?

Я пробовал издеваться над функцией, но получил сообщение об ошибке «Не удалось найти команду».

Я также попытался добавить пустую «фиктивную» функцию в описываемом блоке. Это не дает мне вышеуказанную ошибку, но она не издевается над функцией внутри скрипта правильно.

У меня есть два файла. Один для проведения тестов и другой, который содержит функции и вызовы функций. Ниже приведены два примера:

File1.ps1

Function Backup-Directory([switch]$IsError) 
{ 
    If($IsError) 
    { 
     Write-Error "Error" 
     Exit 1 
    } 
} 

Backup-Directory $true 

File2.Tests.ps1

$here = (Split-Path -Parent $MyInvocation.MyCommand.Path) -replace '\\test', '\main' 
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.' 
$productionFile = "$here\$sut" 

Describe "File1" { 

    Context "When the Back-Directory outputs an error." { 

     # Arrange 
     Mock Back-Directory { } 
     Mock Write-Error 

     # Act 
     & $productionFile 
     $hasSucceeded = $? 

     # Assert 
     It "Calls Backup-Directory" { 
      Assert-MockCalled Backup-Directory -Exactly 1 -ParameterFilter { 
       $IsError -eq $true 
      } 
     } 

     It "Writes error message." { 
      Assert-MockCalled Write-Error -Exactly 1 -ParameterFilter { 
       $Message -eq "Error" 
      } 
     } 

     It "Exits with an error." { 
      $hasSucceeded | Should be $false 
     } 
    } 
} 
+0

Нам потребуется дополнительная информация, по крайней мере, и, возможно, чтобы увидеть код. Функция, которую вы хотите высмеять, находится в том же файле, который вы используете для тестирования? – EBGreen

ответ

4

Я не думаю, что это возможно. По крайней мере, с вашей текущей реализацией. Я задал этот вопрос еще некоторое время назад ... Pester Issue 414

НО вы могли бы разделить эту внутреннюю функцию на другой файл сценария в том же каталоге, что позволяет вам тестировать блок и издеваться над ним. Вы просто должны бы расставить все точки Source функции в основной файл сценария, чтобы иметь возможность использовать его:

Main-Function.ps1:

# Main script 
function Main-Function { 
    # if debugging, set moduleRoot to current directory 
    if ($MyInvocation.MyCommand.Path) { 
     $moduleRoot = Split-Path -Path $MyInvocation.MyCommand.Path 
    }else { 
     $moduleRoot = $PWD.Path 
    } 

    # dot source the inner function 
    . "$moduleRoot\Inner-Function.ps1" 

    Write-Output "This is the main script. Calling the inner function" 

    Inner-Function 

    Write-Output "Back in the main script" 
} 

Inner-Function.ps1:

function Inner-Function { 
    Write-Output "This is the inner function" 
} 

Main-Function.Tests.ps1:

$moduleRoot = Split-Path -Parent $MyInvocation.MyCommand.Path 

# Load Testing Function 
. "$moduleRoot\Main-Function.ps1" 

# Load Supporting Functions 
. "$moduleRoot\Inner-Function.ps1" 

Describe 'Main Script' { 
    Mock Inner-Function { return "This is a mocked function" } 

    It 'uses the mocked function' { 
     (Main-Function -match "This is a mocked function") | Should Be $true 
    } 
} 

Это действительно хороший подход, потому что мы можем проверить блок внутренней FUNC и по мере роста логики добавление тестов к нему очень просто (и может выполняться изолированно от остальных скриптов/функций).

Inner-Functions.Tests.ps1:

$moduleRoot = Split-Path -Parent $MyInvocation.MyCommand.Path 

# Load Testing Function 
. "$moduleRoot\Inner-Function.ps1" 

Describe 'Inner Function' { 
    It 'outputs some text' { 
     Inner-Function | Should Be "This is the inner function" 
    } 
} 

Есть два основных момента здесь ...

Нахождение зависимой функции местоположения, независимо от текущего каталога исполнения ...

if ($MyInvocation.MyCommand.Path) { 
     $moduleRoot = Split-Path -Path $MyInvocation.MyCommand.Path 
    }else { 
     $moduleRoot = $PWD.Path 
    } 

И

Dot Sourcing в зависимости от функций в основной функции а также единичные тестовые файлы ... . "$moduleRoot\Inner-Function.ps1"

Split-Path -Path $MyInvocation.MyCommand.Path находится в пользовательской сессии $null, но НЕ будет $null, когда вызывается из контекста исполнения. Значит, вы можете быть в C:\users\nhudacin и загружать этот скрипт/модуль правильно. В противном случае вам придется всегда выполнять этот скрипт/модуль из того же каталога, где он находится, не используя переменную $MyInvoation.