簡體   English   中英

如何使用 Pester 模擬匿名高級函數中的函數

[英]How to use Pester to mock functions in anonymous advanced functions

我最近發現我不需要使用 Import-Module 來使用我的高級 powershell 函數,我可以在 ps1 文件中匿名定義一個函數。

不幸的是,我的 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 {
}

所以我找到了一種方法,通過在 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 {
 }

這樣,在 dot 采購我的 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
        }
    }
}

PowerShell 腳本(.ps1 文件)在它們自己的范圍內運行,稱為腳本范圍。 所以我認為 Pester 很難模擬它使用的 cmdlet。

在解決方法中,您被迫聲明一個函數,該函數可以看到 cmdlet 的模擬版本。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM