You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When writing unit tests, and mocking complex objects, I want to make use of New-MockObject.
New-MockObject wires up members to the PSObject wrapper, hiding the real properties (or methods). This is a good thing.
New-MockObject avoids Add-Member to achieve this, likely because Add-Member is not regarded as being particularly fast.
This has an unfortunate side-effect if Select-Object is being used in the test subject's code. Select-Object replaces the PSObject wrapper on the selected object, discarding NoteProperty members added via PSObject.Properties.
The following tests describe the expected behaviour. All tests should pass:
$container=New-PesterContainer-ScriptBlock {
Context 'When using PSObject.Properties.Add' {
BeforeAll {
$mockObject=New-MockObject-Type object -Properties @{
Nested=New-MockObject object -Properties @{
Name='Value'
}
}
}
It 'allows access to the property using the member dereference operator' {
$mockObject.Nested.Name| Should -Be 'Value'
}
It 'allows access to the property using Select-Object' {
# This test currently fails.$mockObject|Select-Object-ExpandProperty Nested |Select-Object-ExpandProperty Name |
Should -Be 'Value'
}
}
Context 'When using Add-Member' {
BeforeAll {
$addMember=New-MockObject-Type object |Add-Member-PassThru -NotePropertyName 'Nested'-NotePropertyValue (
New-MockObject object |Add-Member-PassThru -NotePropertyName 'Name'-NotePropertyValue 'Value'
)
}
It 'allows access to the property using the member dereference operator' {
$mockObject.Nested.Name| Should -Be 'Value'
}
It 'allows access to the property using Select-Object' {
# This test currently fails.$addMember|Select-Object-ExpandProperty Nested |Select-Object-ExpandProperty Name |
Should -Be 'Value'
}
}
}
Invoke-Pester-Container $container-Output Detailed
Steps To Reproduce
This problem is exhibited by any object accessed by Select-Object where members have been added using .PSObject.Properties.
$object= [object]::new()
$object.PSObject.Properties.Add(
[PSNoteProperty]::new(
'Nested',
[object]::new()
)
)
$object.Nested.PSObject.Properties.Add(
[PSNoteProperty]::new(
'Name','Value'
)
)
# This works$object.Nested.Name# this doesn't$object|Select-Object-ExpandProperty Nested |Select-Object-ExpandProperty Name
It is an unfortunate side effect of this problem which affects Pester. However, Pester is the far easier "thing to fix" than PowerShell, so Add-Member may be used to work-around this problem.
Describe your environment
Pester version : 5.4.0 C:\Development\_modules\Pester\5.4.0\Pester.psm1
PowerShell version : 7.3.6
OS version : Microsoft Windows NT 10.0.19045.0
Possible Solution?
No response
The text was updated successfully, but these errors were encountered:
Thanks for the detailed report and troubleshooting. Will need to compare and benchmark later, but initial thought is that we could probably use Add-Member in New-MockObject specifically. As it's an optional helper, the performance savings of the current .NET approach are not worth the trouble. Hopefully there's no major side effects of changing.
We use the property access directly for performance, if that has bugs that we cannot fix, I am okay with reverting back to Add-Member under New-MockObject. @chrisdent-de Please consider PRing this. Please use the add-member from safeCommands table.
Checklist
What is the issue?
When writing unit tests, and mocking complex objects, I want to make use of
New-MockObject
.New-MockObject
wires up members to the PSObject wrapper, hiding the real properties (or methods). This is a good thing.New-MockObject
avoidsAdd-Member
to achieve this, likely becauseAdd-Member
is not regarded as being particularly fast.This has an unfortunate side-effect if
Select-Object
is being used in the test subject's code.Select-Object
replaces the PSObject wrapper on the selected object, discarding NoteProperty members added viaPSObject.Properties
.https://github.com/PowerShell/PowerShell/blob/master/src/Microsoft.PowerShell.Commands.Utility/commands/utility/Select-Object.cs#L573
Expected Behavior
The following tests describe the expected behaviour. All tests should pass:
Steps To Reproduce
This problem is exhibited by any object accessed by
Select-Object
where members have been added using.PSObject.Properties
.It is an unfortunate side effect of this problem which affects Pester. However, Pester is the far easier "thing to fix" than PowerShell, so
Add-Member
may be used to work-around this problem.Describe your environment
Possible Solution?
No response
The text was updated successfully, but these errors were encountered: