Pester
Pester copied to clipboard
Problems with removing parameter validation
1. General summary of the issue
Removing the parameter validation as part of the Mock definition currently fails in several cases when running the mocks.
ValidateNotNullOrEmpty
- If the parameter whose validation is removed is also a Mandatory parameter, passing $null or an empty array (if supported by the type conversions) also fails.
This seems to stem from the way powershell itself handles the binding process between arguments and parameters.
Interestingly, the errors differs depending on the invocation of the function:
- If $null or an empty array is passed as a parameter for the function, it throws a terminating error, thus making the test fail.
- if $null is bound to the parameter from the pipeline, the function throws a non-terminating error and the test pass
Related Info:
- https://stackoverflow.com/a/25465128/2158047
- ArgumentTransformationAttribute
ValidateNotNull*
Similar to ValidateNotNullOrEmpty validation
Example tests:
Describe 'RemoveParameterValidation' {
BeforeAll {
$testCases = @(
@{ Name = 'parameter ReferenceObject is null'; Block = { Test-Validation -ReferenceObject $null } }
@{ Name = 'parameter ReferenceObject is an empty array'; Block = { Test-Validation -ReferenceObject @() } }
@{ Name = 'parameter ReferenceObject is empty string'; Block = { Test-Validation -ReferenceObject '' } }
@{ Name = 'receiving $null from pipeline'; Block = { $null | Test-Validation } }
@{ Name = 'receiving empty array from pipeline'; Block = { @(@()) | Test-Validation } }
@{ Name = 'receiving empty string from pipeline'; Block = { '' | Test-Validation } }
)
}
Context 'ValidateNotNullOrEmpty' {
Context 'Mandatory parameter' {
BeforeAll {
function Test-Validation {
param(
[Parameter(Mandatory, ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[object[]]
$ReferenceObject
)
$Count
}
}
It 'does not throw when <Name>' -TestCases $testCases {
param($Block)
Mock Test-Validation -RemoveParameterValidation ReferenceObject { }
$Block | Should -Not -Throw
}
}
Context 'Non-Mandatory parameter' {
BeforeAll {
function Test-Validation {
param(
[Parameter(ValueFromPipeline)]
[ValidateNotNullOrEmpty()]
[object[]]
$ReferenceObject
)
$Count
}
}
It 'does not throw when <Name>' -TestCases $testCases {
param($Block)
Mock Test-Validation -RemoveParameterValidation ReferenceObject { }
$Block | Should -Not -Throw
}
}
}
}
-->
2. Describe Your Environment
Pester version : master (v 4.8.1) PowerShell version : 6.2.1 OS version : Microsoft Windows NT 10.0.17134.0
Pester version : master (v 4.8.1) PowerShell version : 5.1.17134.765 OS version : Microsoft Windows NT 10.0.17134.0
3. Expected Behavior
Test should pass
4.Current Behavior
Tests fail
5. Possible Solution
TBD
6. Context
https://github.com/pester/Pester/pull/1278#issuecomment-498976454 #601
@nohwnd @DarkLite1 the main issue seems to derive from the fact that Mandatory parameters does not allow passing $null or empty collections.
A possible solution could be either:
- Remove the Mandatory requirement for the parameter. That would make the tests automatically pass
- Add the corresponding
AllowNull,AllowEmptyStringorAllowEmptyCollectionattributes depending on the parameter object type.
My concern here is that we would be doing more modifications that what the user would be expecting
@nohwnd Any suggestions for this?
Not sure. When we remove the mandatory, will the parameter set still resolve correctly, in case there are multiple? Imho that is better than explaining that even though you removed the param valudation you still need to provide null into it.
Add -RemoveMandatory?
@fflaten there are no other people complaining or any upvotes, I would keep it not implemented, unless you feel like it is really needed.
Should we close old issues like this as "not planned" to clear backlog?