无法在Pester测试中Mock New-Object OfficeOpenXml.ExcelPackage
问题原因及解决方案
你的Mock不生效核心是ParameterFilter的匹配条件完全错误,导致Pester找不到对应的Mock,只能执行真实的New-Object命令:
错误点分析
- 参数名错误:
$_._ArgumentList是错误写法,正确参数名应为$_.ArgumentList(多了一个下划线)。 - 匹配值错误:你在Filter里检查
ArgumentList -eq 'Sheet1',但实际调用New-Object时传入的是Excel文件路径C:\path\to\file.xlsx,Sheet1是工作表名,根本不是New-Object的参数,所以这个条件永远不成立。
修正后的测试代码
Describe "Clear-ExcelWorksheet" { Context "When clearing a worksheet" { It "should clear the worksheet cells and save the package" { # 修正Mock的ParameterFilter,匹配正确的类型和文件路径参数 Mock -CommandName New-Object -ParameterFilter { $_.TypeName -eq 'OfficeOpenXml.ExcelPackage' -and $_.ArgumentList -eq 'C:\path\to\file.xlsx' } -MockWith { param($Type, $ArgumentList) [PSCustomObject] @{ Workbook = [PSCustomObject] @{ Worksheets = @{ Item = @{ "Sheet1" = [PSCustomObject] @{ Cells = [PSCustomObject] @{} | Add-Member -MemberType ScriptMethod -Name Clear -Value { } -PassThru } } } } | Add-Member -MemberType ScriptMethod -Name Save -Value { } -PassThru | Add-Member -MemberType ScriptMethod -Name Dispose -Value { } -PassThru } } # Arrange $ExcelFilePath = "C:\path\to\file.xlsx" $WorkSheetName = "Sheet1" # Act Clear-ExcelWorksheet -ExcelFilePath $ExcelFilePath -WorkSheetName $WorkSheetName # Assert Should -Invoke -CommandName New-Object -Exactly 1 -Scope It } } }
更灵活的匹配方式
如果不想硬编码文件路径,可以用变量引用,或者直接检查ArgumentList是否不为空(根据测试场景调整):
# 使用变量匹配 Mock -CommandName New-Object -ParameterFilter { $_.TypeName -eq 'OfficeOpenXml.ExcelPackage' -and $_.ArgumentList -eq $ExcelFilePath } -MockWith { ... }
额外注意事项
- 确保
Clear-ExcelWorksheet函数在测试代码之前被加载,或者在测试块内导入包含该函数的模块。 - 若需测试不同文件路径,建议将Mock放在
Context块内,或使用BeforeEach复用Mock逻辑。
内容的提问来源于stack exchange,提问作者Kurtis
相关产品推荐
相关产品推荐

