powershellmockingpester

Cannot get Pester Test to use Mock for "New-Object OfficeOpenXml.ExcelPackage"


I have been unable to get the mock for New-Object to work.

Below is the function and the test inline.

Import-Module ImportExcel -Force

function Clear-ExcelWorksheet {
    [CmdletBinding()]
    param (

        [Parameter(Mandatory = $true)]
        [string]$ExcelFilePath,

        [Parameter(Mandatory = $true)]
        [string]$WorkSheetName

    )

    try {

        $package = New-Object OfficeOpenXml.ExcelPackage -ArgumentList $ExcelFilePath
       <# 
        $worksheet = $package.Workbook.Worksheets.Item[$WorkSheetName]
        $worksheet.Cells.Clear()
        $package.Save()
        $package.Dispose()   
        #>

    }
    catch {
        $message = "Error occurred clearing the Worksheet: $_"
        Write-Output $message
        throw $message
    }

    Write-Output "Cleared worksheet $WorkSheetName in $ExcelFilePath"
}

The tests:

Describe "Clear-ExcelWorksheet" {
    
    Context "When clearing a worksheet" {
        
        It "should clear the worksheet cells and save the package" {
           
            # Mock the necessary cmdlets and methods
           
            Mock -CommandName New-Object -ParameterFilter{$_.TypeName -eq 'OfficeOpenXml.ExcelPackage' -and $_._ArgumentList -eq 'Sheet1'} -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
        }
   
    }
}

When I walk through the debugger, I can see it is creating the actual OfficeOpenXml.ExcelPackage object rather than the mock. I'm using PowerShell 7 and Pester 5.7.1 which are both current. I figured it was a scoping issue, so I moved the Mock all the way into the It section, but still it is not using it.


Solution

  • If the original method is being invoked then the -ParameterFilter conditions are not being met.

    Try changing the parameter filter to argument names instead of $_.<Argument>

    Mock New-Object -ParameterFilter { $TypeName -eq "OfficeOpenXml.ExcelPackage" }