Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/functions/Mock.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,14 @@ function Create-MockHook ($contextInfo, $InvokeMockCallback) {
if ($cmdletBinding -ne '[CmdletBinding()]') {
$cmdletBinding = $cmdletBinding.Insert($cmdletBinding.Length - 2, ',')
}
# When the cmdlet has no explicit DefaultParameterSetName and its dynamic parameters
# introduce multiple named parameter sets, PowerShell cannot resolve which set applies
# when the mock is called without arguments. Injecting '__AllParameterSets' as the
# default makes the no-argument call succeed, matching the real cmdlet's behaviour. (#1531)
if ([string]::IsNullOrEmpty($metadata.DefaultParameterSetName)) {
$cmdletBinding = $cmdletBinding.Insert($cmdletBinding.Length - 2, "DefaultParameterSetName='__AllParameterSets'")
$cmdletBinding = $cmdletBinding.Insert($cmdletBinding.Length - 2, ',')
}
$cmdletBinding = $cmdletBinding.Insert($cmdletBinding.Length - 2, 'PositionalBinding=$false')
}

Expand Down
17 changes: 17 additions & 0 deletions tst/functions/Mock.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2027,6 +2027,23 @@ Describe 'Mocking commands with potentially ambiguous parameter sets' {
}
}

Describe 'Mocking a cmdlet with multiple non-default parameter sets and no DefaultParameterSetName (#1531)' {
# Get-PackageSource has two provider-specific parameter sets (NuGet and PowerShellGet) with no
# default, and its dynamic parameters introduce those sets. Without a DefaultParameterSetName in
# the generated bootstrap proxy, PowerShell cannot resolve the parameter set when the mock is
# called with no arguments, producing "Parameter set cannot be resolved". The fix injects
# DefaultParameterSetName='__AllParameterSets' into the proxy [CmdletBinding()] for any cmdlet
# whose metadata has an empty DefaultParameterSetName.

It 'Can mock Get-PackageSource and call it with no arguments' -Skip:($null -eq (Get-Command Get-PackageSource -ErrorAction SilentlyContinue)) {
Mock Get-PackageSource { [PSCustomObject]@{ Name = 'MockedSource'; ProviderName = 'NuGet' } }

$result = Get-PackageSource
$result.Name | Should -Be 'MockedSource'
Should -Invoke Get-PackageSource -Times 1
}
}

Describe 'When mocking a command that has an ArgumentList parameter with validation' {
BeforeAll {
Mock Start-Process { return 'mocked' }
Expand Down
Loading