You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Pester v5验证PowerShell Mock函数的传入参数值

Pester v5 如何校验Mock函数接收的参数是否正确

问题描述

我用PowerShell编写了一个函数,正尝试使用Pester v5对其进行测试,下方代码示例包含了待测函数与对应的Pester测试用例。
我想要验证传入被Mock的函数Save-Report的参数$FileName是否正确,请问该如何实现?

注意事项

  • 我清楚Mock函数Add-StringToFileName时会返回测试值来设置$Filename参数,但我仍需要测试该值能完整传递到最终调用环节且未被修改。
  • 这类校验逻辑我后续测试也会频繁用到,因此想要了解具体的实现方案。

待测函数

Function Invoke-ReportDownloader
{
    [CmdletBinding()]
    Param
    (
        # 用于连接数据库的命令对象
        [Parameter(Mandatory)]
        [System.Data.Odbc.OdbcCommand]$Command,

        # 包含待获取报表项的XML元素
        [Parameter(Mandatory)]
        [System.Xml.XmlElement]$ReportItem,

        # 包含配置参数的哈希表
        [Parameter(Mandatory)]
        [hashtable]$ConfigParams,

        # 报表对应的SEMO参与者对象
        [Parameter(Mandatory)]
        [System.Data.DataRow]$Participant
    )

    # 报表不支持则跳过
    $ReportName = $ReportItem.ReportName
    if (-not (Test-ReportSupported $Command $ReportName)) {
        $Logger.Warning("Report: $($ReportName) is not currently supported")
        return
    }

    # (Kanban-7940) 如果报表项配置的文件名不含时间戳,自动追加对应日期,避免同类型报表覆盖
    $Filename = $ReportItem.FileName
    if (-not (Test-TimestampIncluded -Filename $Filename)) {
        $FileName = Add-StringToFileName -Path $Filename -SubString $ReportItem.Date
    }

    # 数据库已存在该报表则跳过
    if (Test-MarketReportInDatabase $Command $ReportItem) {
        return
    }

    Get-Report $ConfigParams $Participant $ReportItem

    # 响应包含失败信息则抛出异常
    $ReportSuccessParams = @{
        ResponsePath = $ConfigParams.BmResponsePath
        BaseName = $ConfigParams.ReportFilter
    }
    if (-not (Test-SuccessfulResponse @ReportSuccessParams)) {
        throw "Unsuccessful response from BM"
    }

    $SaveReportParams = @{
        RawPath = $ConfigParams.RawPath
        XmlResponsePath = $ConfigParams.XmlResponsePath
        Filename = $FileName
    }
    Save-Report @SaveReportParams
}

现有单元测试代码

Describe 'Invoke-ReportDownloader' {
    BeforeAll {
        # 初始化测试用$Cmd对象
        # 初始化测试用$Logger对象
        # 初始化测试用$ReportItem对象
        # 初始化测试用$ConfigParams对象
    }

    Context "文件名不含时间戳场景" {

        BeforeAll {
            Mock Test-ReportSupported { return $true }
            Mock Test-MarketReportInDatabase { return $false }
            Mock Get-Report
            Mock Test-SuccessfulResponse { return $true }
            Mock Save-Report
        }

        BeforeEach {
            $Script:ReportDownloaderParams = @{
                Command = $Script:Cmd
                ReportItem = $ReportItem
                ConfigParams = $Script:ConfigParams
                Participant = $Script:Participant
            }
        }

        It "应该将带时间戳的文件名传入保存方法" {
            $TestFileName = "test_string_20210101"
            Mock Add-StringToFileName { return $TestFileName }
            Invoke-ReportDownloader @Script:ReportDownloaderParams
            Should -InvokeVerifiable Save-Report
            # 此处需要校验传入Save-Report的$FileName参数是否正确
        }
    }
}

解决方案

你可以通过以下3种常用方案实现参数校验,覆盖不同的使用场景:

方案1:使用Should -Invoke的-ParameterFilter参数(最常用)

这是Pester原生支持的参数校验方式,无需额外封装,直接在It块的注释位置替换为以下代码即可:

# 校验Save-Report刚好被调用1次,且传入的Filename参数等于预设的测试值
Should -Invoke Save-Report -ParameterFilter { $Filename -eq $TestFileName } -Exactly 1 -Scope It

你可以在-ParameterFilter的脚本块中写任意匹配逻辑,比如校验文件名格式、包含特定字符串等,灵活度很高。

方案2:封装参数过滤规则到Mock定义(适合高频复用场景)

如果后续大量测试用例都需要校验Save-Report的Filename参数,可以把校验逻辑直接封装到Mock定义中,标记为可验证,后续只需调用Should -InvokeVerifiable即可完成校验:

# 在Context的BeforeAll中定义带参数过滤的可验证Mock
Mock Save-Report -Verifiable -ParameterFilter { $Filename -eq $expectedFileName }

不同测试用例可以根据需要重写Mock的参数过滤规则,匹配不同的期望文件名。

方案3:获取Mock调用历史做自定义断言(适合复杂校验场景)

如果需要对参数做更复杂的校验(比如拆分文件名检查日期格式、校验后缀等),可以通过Get-MockCallHistory获取所有调用的参数列表,单独做断言:

# 执行完待测函数后添加以下代码
$saveReportCalls = Get-MockCallHistory -CommandName Save-Report
# 校验调用次数
$saveReportCalls.Count | Should -Be 1
# 校验Filename参数值
$saveReportCalls[0].Arguments.Filename | Should -Be $TestFileName
# 还可以扩展更多自定义校验逻辑

内容的提问来源于stack exchange,提问作者gerard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 13:45:05