How to Assert Arrays ?

653 views
Skip to first unread message

Frank Behrens

unread,
May 9, 2014, 11:38:14 AM5/9/14
to pes...@googlegroups.com
Hello again,

today I refactored some code I have inherited.
I was a little proud as a managed to use the powershell piping to filter an array of patters through an array of values,
where the non matching pattern are selected.

As I love testing and here so pester, i wrote my pester tests,
which in th end leads to a surprise.

I already have found out that its kind of hard to learn about powershells implicit conversions from and to arrays.
That is also true in petes tests, so that this is passing.

Describe "Arrays" {
  it "why passing" {
    @(1,1,1) | should be @(1,2)
    1,1,1 | should be 1,2
  }
}

So how do i test my filtering function correctly with pester as it operates on arrays ?

Just wanna throw in a suggestion which you might be helpful:

For debug purposes i created a little function to serialise simple structured Objects (Array, hashtable).
This uses newlines to reveal the structure by indentation.
The name and functionallity are copied from ruby.

iE 
inspect @(1,2) | Should Be @"
@(
1,
2)
"@


This could be refactored into a matcher, like

@(1,1,2) | should inspect "@(1,1,2)"

which would then be helpful to test such functionalitiy described above.

Frank

Scott Muc

unread,
May 10, 2014, 7:08:03 PM5/10/14
to Frank Behrens, pes...@googlegroups.com
Thanks Frank! That looks really slick. I don't have a working Pester dev environment right now so I can't play around with it right now, but I hope someone else out there can take a look.

Cheers,
Scott

PS Getting my dev env is on my TODO
PPS Sorry Frank for the double e-mail, forgot to reply-all to the group


--
You received this message because you are subscribed to the Google Groups "Pester" group.
To unsubscribe from this group and stop receiving emails from it, send an email to pester+un...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Frank Behrens

unread,
Nov 3, 2014, 8:11:47 AM11/3/14
to pes...@googlegroups.com, fbeh...@gmail.com
Hi again,

some months later I revisit this code, wanting to write a post, which I have already written.
Today I know that pesters `should be` sematic is just equivalent with the `-eq` operator.

When I have functions that return array, 
how do I test them ?

I might contribute.

Frank

Dave Wyatt

unread,
Nov 3, 2014, 8:36:08 AM11/3/14
to pes...@googlegroups.com, fbeh...@gmail.com
In PowerShell's pipeline can be a bit annoying when it comes to arrays.  We may look into changing this behavior in v4, but it would be a breaking change from how things work today.  Here's how I addressed this problem in https://github.com/dlwyatt/RefactoringPowerShellWithPester/blob/master/StringTokens.Tests.ps1 :

function Assert-ArraysAreEqual
{
    param (
        [object[]] $First,
        [object[]] $Second,
        [scriptblock] $Assertion = { $args[0] | Should BeExactly $args[1] }
    )

    if ($null -eq $First)  { $First = @() }
    if ($null -eq $Second) { $Second = @() }

    $First.Count | Should Be $Second.Count
    for ($i = 0; $i -lt $First.Count; $i++)
    {
        & $Assertion $First[$i] $Second[$i]
    }
}


Then, down in my It blocks, I would just call this function:

        It 'Produces empty tokens when multiple consecutive delimiters are found' {
            $line = "One`t`tTwo Three"
            $expected = 'One', '', 'Two', 'Three'
            $result = @(Get-StringToken -String $line)

            Assert-ArraysAreEqual $result $expected
        }

When doing more complicated comparisons (where the elements of the array can't be simply compared with -eq), you can pass in another script block to do the comparison of each element:

        It 'Outputs an object for each line with multiple lines of input' {
            $strings = 'One Two', 'Three Four'
            $expected = @(
                @{ Tokens = 'One', 'Two' }
                @{ Tokens = 'Three', 'Four' }
            )

            $result = @($strings | Get-StringToken -GroupLines)

            Assert-ArraysAreEqual $result $expected -Assertion ${function:Compare-LineGroupObjects}
        }

-Assertion is probably a bad name for that parameter.  Maybe -Comparer or something like that would be more appropriate, but you get the idea.  Either way, I try to avoid piping arrays to Should, because the behavior is weird.  Instead, I set up all of my tests to send single values (scalars) to Should.

Frank Behrens

unread,
Nov 4, 2014, 5:21:53 PM11/4/14
to pes...@googlegroups.com, fbeh...@gmail.com
Thanks Dave,

I reuse your Assert-ArraysAreEqual function, which solved my current problem.

Frank
Reply all
Reply to author
Forward
0 new messages