如何在 Pester 中将两个数组与自定义对象进行比较
How to compare two arrays with custom objects in Pester
我们正在努力让 Pester 测试失败或通过,这取决于 array
中 objects
的相等性。
测试。ps1
#require Assert
#require Pester
$Expected = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
)
$Actual = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
)
Describe 'comparing arrays' {
Context 'Assert-Equivalent' {
it 'should be green' {
Assert-Equivalent -Actual $Expected -Expected $Expected
}
it 'should be green' {
Assert-Equivalent -Actual $Actual -Expected $Expected
}
it 'should be red' {
$Wrong = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'WROMG';Name2 = 'Text2'}
)
Assert-Equivalent -Actual $Wrong -Expected $Expected
}
}
Context 'Should be' {
it 'should be green' {
$Expected | Should -Be $Expected
}
it 'should be green' {
$Actual | Should -Be $Expected
}
it 'should be red' {
$Wrong = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'WROMG';Name2 = 'Text2'}
)
$Wrong | Should -Be $Expected
}
}
}
我们似乎做错了。我们是否使用了错误的 CmdLets?或者还有另一种检查方法吗?有时 array
也只是另一个对象的 属性。因此需要进行深入比较。
当我想将某些 'complex' 对象与 Pester 进行比较时,我使用 ConvertTo-Json。这并不理想,因为如果类型不匹配可能会出现一些假阴性,但它通常可以完成工作。
$Expected = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
)
$Actual = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
)
Describe 'comparing arrays' {
Context 'Assert-Equivalent' {
it 'should be green' {
Assert-Equivalent -Actual ($Expected | ConvertTo-Json) -Expected ($Expected | ConvertTo-Json)
}
it 'should be green' {
Assert-Equivalent -Actual ($Actual | ConvertTo-Json) -Expected ($Expected | ConvertTo-Json)
}
it 'should be red' {
$Wrong = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'WROMG';Name2 = 'Text2'}
)
Assert-Equivalent -Actual ($Wrong | ConvertTo-Json) -Expected ($Expected | ConvertTo-Json)
}
}
Context 'Should be' {
it 'should be green' {
($Expected | ConvertTo-Json) | Should -Be ($Expected | ConvertTo-Json)
}
it 'should be green' {
($Actual | ConvertTo-Json) | Should -Be ($Expected | ConvertTo-Json)
}
it 'should be red' {
$Wrong = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'WROMG';Name2 = 'Text2'}
)
($Wrong | ConvertTo-Json) | Should -Be ($Expected | ConvertTo-Json)
}
}
}
这也取决于你想在这个问题上有多严格,例如:
- 数组中对象的顺序重要吗?
- 您要对属性进行类型转换吗?
反正我为此写了一个小帮手:
Function Should-BeObject {
Param (
[Parameter(Position=0)][Object[]]$b, [Parameter(ValueFromPipeLine = $True)][Object[]]$a
)
$Property = ($a | Select-Object -First 1).PSObject.Properties | Select-Object -Expand Name
$Difference = Compare-Object $b $a -Property $Property
Try {"$($Difference | Select-Object -First 1)" | Should -BeNull} Catch {$PSCmdlet.WriteError($_)}
}
您可以这样调用它:
,$Actual | Should-BeObject $Expected
(注意,$Actual
前面的逗号)
我自己没有尝试过,但是 https://github.com/nohwnd/Assert 库中有一个 Assert-Equivalent
cmdlet 看起来很有前途。
虽然这是一个老问题,但我想展示另一种方法来做到这一点。 Compare-Object 在比较复杂对象时会派上用场。
$Expected = @(
[PSCustomObject]@{Name1 = 'Text1'; Name2 = 'Text2' }
[PSCustomObject]@{Name1 = 'Text1'; Name2 = 'Text2' }
)
$Actual = @(
[PSCustomObject]@{Name1 = 'Text1'; Name2 = 'Text2' }
[PSCustomObject]@{Name1 = 'Text1'; Name2 = 'Text2' }
)
Describe 'object equivalence' {
It 'eq' {
$eqs = $Actual | Compare-Object -ReferenceObject $Expected -Property @('Name1', 'Name2') -IncludeEqual | Select-Object -ExpandProperty SideIndicator
$eqs | ForEach-Object { $_ | Should -Be '==' }
}
}
请注意,您需要指定要比较的所有属性。多看看 here.
我们正在努力让 Pester 测试失败或通过,这取决于 array
中 objects
的相等性。
测试。ps1
#require Assert
#require Pester
$Expected = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
)
$Actual = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
)
Describe 'comparing arrays' {
Context 'Assert-Equivalent' {
it 'should be green' {
Assert-Equivalent -Actual $Expected -Expected $Expected
}
it 'should be green' {
Assert-Equivalent -Actual $Actual -Expected $Expected
}
it 'should be red' {
$Wrong = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'WROMG';Name2 = 'Text2'}
)
Assert-Equivalent -Actual $Wrong -Expected $Expected
}
}
Context 'Should be' {
it 'should be green' {
$Expected | Should -Be $Expected
}
it 'should be green' {
$Actual | Should -Be $Expected
}
it 'should be red' {
$Wrong = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'WROMG';Name2 = 'Text2'}
)
$Wrong | Should -Be $Expected
}
}
}
我们似乎做错了。我们是否使用了错误的 CmdLets?或者还有另一种检查方法吗?有时 array
也只是另一个对象的 属性。因此需要进行深入比较。
当我想将某些 'complex' 对象与 Pester 进行比较时,我使用 ConvertTo-Json。这并不理想,因为如果类型不匹配可能会出现一些假阴性,但它通常可以完成工作。
$Expected = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
)
$Actual = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
)
Describe 'comparing arrays' {
Context 'Assert-Equivalent' {
it 'should be green' {
Assert-Equivalent -Actual ($Expected | ConvertTo-Json) -Expected ($Expected | ConvertTo-Json)
}
it 'should be green' {
Assert-Equivalent -Actual ($Actual | ConvertTo-Json) -Expected ($Expected | ConvertTo-Json)
}
it 'should be red' {
$Wrong = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'WROMG';Name2 = 'Text2'}
)
Assert-Equivalent -Actual ($Wrong | ConvertTo-Json) -Expected ($Expected | ConvertTo-Json)
}
}
Context 'Should be' {
it 'should be green' {
($Expected | ConvertTo-Json) | Should -Be ($Expected | ConvertTo-Json)
}
it 'should be green' {
($Actual | ConvertTo-Json) | Should -Be ($Expected | ConvertTo-Json)
}
it 'should be red' {
$Wrong = @(
[PSCustomObject]@{Name1 = 'Text1';Name2 = 'Text2'}
[PSCustomObject]@{Name1 = 'WROMG';Name2 = 'Text2'}
)
($Wrong | ConvertTo-Json) | Should -Be ($Expected | ConvertTo-Json)
}
}
}
这也取决于你想在这个问题上有多严格,例如:
- 数组中对象的顺序重要吗?
- 您要对属性进行类型转换吗?
反正我为此写了一个小帮手:
Function Should-BeObject {
Param (
[Parameter(Position=0)][Object[]]$b, [Parameter(ValueFromPipeLine = $True)][Object[]]$a
)
$Property = ($a | Select-Object -First 1).PSObject.Properties | Select-Object -Expand Name
$Difference = Compare-Object $b $a -Property $Property
Try {"$($Difference | Select-Object -First 1)" | Should -BeNull} Catch {$PSCmdlet.WriteError($_)}
}
您可以这样调用它:
,$Actual | Should-BeObject $Expected
(注意,$Actual
前面的逗号)
我自己没有尝试过,但是 https://github.com/nohwnd/Assert 库中有一个 Assert-Equivalent
cmdlet 看起来很有前途。
虽然这是一个老问题,但我想展示另一种方法来做到这一点。 Compare-Object 在比较复杂对象时会派上用场。
$Expected = @(
[PSCustomObject]@{Name1 = 'Text1'; Name2 = 'Text2' }
[PSCustomObject]@{Name1 = 'Text1'; Name2 = 'Text2' }
)
$Actual = @(
[PSCustomObject]@{Name1 = 'Text1'; Name2 = 'Text2' }
[PSCustomObject]@{Name1 = 'Text1'; Name2 = 'Text2' }
)
Describe 'object equivalence' {
It 'eq' {
$eqs = $Actual | Compare-Object -ReferenceObject $Expected -Property @('Name1', 'Name2') -IncludeEqual | Select-Object -ExpandProperty SideIndicator
$eqs | ForEach-Object { $_ | Should -Be '==' }
}
}
请注意,您需要指定要比较的所有属性。多看看 here.