如何在Pester中将两个数组与自定义对象进行比较

时间:2018-06-15 07:23:59

标签: arrays powershell compare pester

我们正在努力让Pester测试失败或通过,具体取决于objectsarray的相等性。

Test.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也只是另一个对象的属性。因此需要深入比较。

4 个答案:

答案 0 :(得分:3)

当我想将一些“复杂”对象与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)
        }
    }
}

答案 1 :(得分:2)

这取决于你想要在这个问题上的严格程度,例如:

  • 数组中对象的顺序是否重要?
  • 您想要对属性进行类型转换吗?

无论如何,我为此写了一个小帮手:

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前面的逗号)

答案 2 :(得分:0)

我自己没有尝试,但是Testcontainers Dockerfile DSL库中有一个Assert-Equivalent cmdlet,看起来很有希望。

答案 3 :(得分:0)

虽然这是一个老问题,但我想展示另一种方法来做到这一点。在比较复杂对象时,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