pester / Pester

Pester is the ubiquitous test and mock framework for PowerShell.
https://pester.dev/
Other
3.05k stars 469 forks source link

Aliases for dynamic parameters cannot be used in ParameterFilter blocks #1275

Open renehernandez opened 5 years ago

renehernandez commented 5 years ago

1. General summary of the issue

Parameter Aliases are not properly handled for dynamic parameters in Mock

The following function and test highlight the issue:

function New-DynamicAttr($ParamDictionary, $Name, $Alias = $null) {
    $attr = New-Object -Type `
        System.Management.Automation.ParameterAttribute
    $attr.Mandatory = $false
    $attr.ParameterSetName = '__AllParameterSets'
    $attributeCollection = New-Object `
        -Type System.Collections.ObjectModel.Collection[System.Attribute]
    $attributeCollection.Add($attr)

    if ($null -ne $Alias) {
        $attr = New-Object -Type `
            System.Management.Automation.AliasAttribute -ArgumentList @($Alias)
        $attributeCollection.Add($attr)
    }

    $dynParam1 = New-Object -Type `
        System.Management.Automation.RuntimeDefinedParameter($Name, [string],
        $attributeCollection)

    $ParamDictionary.Add($Name, $dynParam1)
}

function Test-DynamicParam {
    [CmdletBinding()]
    param(
        [String]$Name
    )

    dynamicparam {
        if ($Name.StartsWith("Hello")) {
            $paramDictionary = New-Object `
                -Type System.Management.Automation.RuntimeDefinedParameterDictionary
             New-DynamicAttr -ParamDictionary $paramDictionary -Name "Path" -Alias "Location"

            return $paramDictionary
        }
    }

    process {
        if ($PSBoundParameters.Path) {
            Write-Host "PSEdition value: $($PSBoundParameters.Path)"
        }
    }
}

Describe 'Usage of Alias in DynamicParams' {
    Context 'Usage of ParameterFilters in Mock' {

       It 'using parameter alias' {
            Mock Test-DynamicParam { "World" } -ParameterFilter {$Location -eq 'Here'}

            Test-DynamicParam -Name "Hello" -Location "Here" | Should -Be 'World'
        }
    }

     Context 'Usage of ParameterFilters in Assert-MockCalled' {
        It 'using parameter alias' {
            Mock Test-DynamicParam { "World" } -ParameterFilter {$Location -eq 'Here'}

            Test-DynamicParam -Name "Hello" -Location "Here" | Should -Be 'World'

            Assert-MockCalled Test-DynamicParam -ParameterFilter {$Location -eq 'Here'}
        }
    }
}

2. Describe Your Environment

Pester version     : 4.7.3 C:\Program Files\PowerShell\Modules\Pester\4.7.3\Pester.psd1
PowerShell version : 6.1.3
OS version         : Microsoft Windows NT 10.0.17134.0

3. Expected Behavior

It should pass

4.Current Behavior

It fails

5. Possible Solution

Add corresponding implementation for dynamic parameter for what was done for regular parameters

6. Context

This is related to #1007 and #1128

renehernandez commented 5 years ago

@nohwnd Can you add this issue to the Better Mock milestone?

renehernandez commented 5 years ago

I have done some preliminary work on this and there are some nuances that we need to account for.

@nohwnd Any thoughts?