2015-06-24 9 views
-1

Недавно я обнаружил, что мне не нужно использовать модуль Import-Module для использования моих расширенных функций powershell, я могу просто определить функцию анонимно в файле ps1.Как использовать Pester для издевательства функций в анонимных расширенных функциях

К сожалению, мои тесты модуля Pester нарушены. Кажется, я не могу высмеять вызов New-Object в списке ниже. Как правило, я хотел бы рассчитать источник кода ниже и получить функцию Get-StockQuote, определенную в моей области. Теперь точка поиска файла ps1 не помогает, потому что я все равно вызываю функцию через имя файла.

Как я могу использовать Pester для проверки приведенного ниже кода с помощью макетной реализации New-Object?

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

# Source listing of the file: Get-StockQuote.ps1 
<# 
.Synopsis 
Looks up a stock quote 
.Description 
Uses the yahoo api to retrieve a recent quote for a given stock. 
.Parameter Symbol 
The stock trading symbol 
.Example 
Get-StockQuote.ps1 -Symbol AMZN 
Prints the following line to the output 
440.84 
#> 
[CmdletBinding()] 
Param(
    [parameter(Mandatory=$false)] 
    [string]$Symbol 
) 
BEGIN { 
    Set-StrictMode -Version 1 
} 
PROCESS { 
    (New-Object System.Net.WebClient).DownloadString("http://finance.yahoo.com/d/quotes.csv?s=$Symbol&f=l1") 
} 
END { 
} 

ответ

0

Так что я нашел способ сделать это путем определения имени функции одним и тем же именем, что и имя файла в блоке BEGIN, и запустив его из блока PROCESS.

[CmdletBinding()] 
Param(
    [parameter(Mandatory=$false)] 
    [string]$Symbol 
) 

BEGIN { 
    Set-StrictMode -Version 1 
    Function Get-StockQuote { 
     [CmdletBinding()] 
     Param(
      [parameter(Mandatory=$false)] 
      [string]$Symbol 
     ) 
     BEGIN{} 
     PROCESS{ 
      (New-Object System.Net.WebClient).DownloadString("http://finance.yahoo.com/d/quotes.csv?s=$Symbol&f=l1") 
     } 
     END{} 
    } 
} 
PROCESS { 
    Get-StockQuote @PSBoundParameters 
} 
END { 
} 

Таким образом, после того, как точка поиска моего файла ps1, у меня будет определение функции в области видимости и Pester начнет работать надлежащим образом.

$here = Split-Path -Parent $MyInvocation.MyCommand.Path 
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".") 

. "$here\$sut" 

Describe "Get a stock quote" { 
    Mock New-Object { 
     $retval = [pscustomobject]@{} 
     Add-Member -InputObject $retval -MemberType ScriptMethod DownloadString { 
      param([string] $url) 
      if ($url -imatch 'AMZN') { 
       return 500.01 
      } 
      return 100.00 
     } 
     return $retval 
    } -ParameterFilter {$TypeName -and ($TypeName -ilike 'System.Net.WebClient') } 
    Context "when called for AMZN" { 
     $result = Get-StockQuote -Symbol AMZN 
     It "Should RETURN 500.01" { 
      $result | should be 500.01 
     } 
    } 
    Context "when called for anything else" { 
     $result = Get-StockQuote -Symbol MSFT 
     It "Should RETURN 100.00" { 
      $result | should be 100.00 
     } 
    } 
} 
0

Скрипты PowerShell (.ps1 файлы) запускаются в их собственной области действия под названием Область сценария. Поэтому я думаю, что Pester будет сложно издеваться над командлетами, которые он использует.

В обходном пути вы вынуждены объявить функцию, которая видит издеваемую версию командлета.