0

still trying to learn Pester, I got a snippet from ChatGPT:

function Get-EvenNumbers {
param(
[Parameter(Mandatory=$true)]
[int]$start,

[Parameter(Mandatory=$true)]
[int]$end
)

$evenNumbers = @()

for ($i = $start; $i -le $end; $i++) {
    if ($i % 2 -eq 0) {
      $evenNumbers += $i
    }
}

return $evenNumbers
}

Pester-code looks like:

Describe "Get-EvenNumbers" {
Context "When the input range is from 1 to 10" {
$start = 1
$end = 10

It "Returns an array of even numbers" {
  $result = Get-EvenNumbers -Start $start -End $end
  $result | Should -BeOfType "System.Array"
  $result | Should -Not -BeNullOrEmpty
  $result | Should -ContainOnly (2, 4, 6, 8, 10)
   }
}

Context "When the input range is from 2 to 9" {
$start = 2
$end = 9

It "Returns an array of even numbers" {
  $result = Get-EvenNumbers -Start $start -End $end
  $result | Should -BeOfType "System.Array"
  $result | Should -Not -BeNullOrEmpty
  $result | Should -ContainOnly (2, 4, 6, 8)
     }
    }
}

and get an error: "[-] Get-EvenNumbers.When the input range is from 1 to 10.Returns an array of even numbers 10ms (8ms|1ms) Expected the value to have type [array] or any of its subtypes, but got 2 with type [int]. at $result | Should -BeOfType "System.Array", C:\Users\Pester\Get-EvenNumbers.Tests.ps1:8 at , C:\Users\Pester\Get-EvenNumbers.Tests.ps1:8 [-] Get-EvenNumbers.When the input range is from 2 to 9.Returns an array of even numbers 13ms (9ms|4ms) Expected the value to have type [array] or any of its subtypes, but got 2 with type [int]. at $result | Should -BeOfType "System.Array", C:\Users\Pester\Get-EvenNumbers.Tests.ps1:20 at , C:\Users\Pester\Get-EvenNumbers.Tests.ps1:20 Tests completed in 177ms Tests Passed: 0, Failed: 2, Skipped: 0 NotRun: 0" But the return value of the function is an [int]array?

Purclot
  • 483
  • 7
  • 22
  • 3
    `$result |...` puts each seperate item (integer) on the [pipeline](https://learn.microsoft.com/powershell/module/microsoft.powershell.core/about/about_pipelines), see:[`#386` Should BeOfType incorrectly asserts type and inconsistently processes type information](https://github.com/pester/Pester/issues/386). As an aside, don't trust Chat-GPT to much as a teacher, besides there are better ways to `Get-EvenNumbers`, you should generally [avoid using the increase assignment operator (`+=`) to create a collection](https://stackoverflow.com/a/60708579/1701026). – iRon Mar 26 '23 at 15:30

1 Answers1

3

Arrays are enumerated when passed through the pipeline, in your example Should is comparing the type of each element of the array and not the array as a whole:

"...but got 2 with type [int]..."

You can use the comma operator , to make your test succeed but note that Should is meant testing the type of an element not to test an array as a whole.

For example, you could define your test as follows:

It 'Should be an integer equal to 2 as first element' {
    $result = Get-EvenNumbers -Start $start -End $end |
        Select-Object -First 1

    $result | Should -BeOfType [int]
    $result | Should -BeExactly 2
}

Or you could also define your test as:

It 'Should return an array of only integers' {
    $result = Get-EvenNumbers -Start $start -End $end
    $result | Should -BeOfType [int]
    $result | Should -BeGreaterThan 1
}

Also your function should be defined in the BeforeAll block and the ranges, $start and $end, should be defined either in the BeforeEach block or inside the It block of each test.

Lastly, not sure what you meant by -ContainOnly, there is no such parameter for Should.

BeforeAll {
    function Get-EvenNumbers {
        param(
            [Parameter(Mandatory=$true)]
            [int] $start,

            [Parameter(Mandatory=$true)]
            [int] $end
        )

        for ($i = $start; $i -le $end; $i++) {
            if ($i % 2 -eq 0) {
                $i
            }
        }
    }
}
Describe 'Get-EvenNumbers' {
    Context 'When the input range is from 1 to 10' {
        BeforeEach {
            $start = 1
            $end = 10
        }
        It 'Returns an array of even numbers' {
            $result = Get-EvenNumbers -Start $start -End $end
            , $result | Should -BeOfType [array]
            $result | Should -Not -BeNullOrEmpty
            $result | Should -BeExactly 2, 4, 6, 8, 10
        }
    }

    Context 'When the input range is from 2 to 9' {
        BeforeEach {
            $start = 2
            $end = 9
        }
        It 'Returns an array of even numbers' {
            $result = Get-EvenNumbers -Start $start -End $end
            , $result | Should -BeOfType [array]
            $result | Should -Not -BeNullOrEmpty
            $result | Should -BeExactly 2, 4, 6, 8
        }
    }
}
Santiago Squarzon
  • 41,465
  • 5
  • 14
  • 37