So I'm having a bit of an issue in PowerShell I wrote a simple script for a class project about Pester testing It looks like this
param ([Parameter(Mandatory, ValueFromPipeline = $true)]$FN, [Parameter(Mandatory)]$OP, [Parameter()]$SN)
$solution
try {
if ($OP -eq ' ') {
$solution = ([long]($FN) [long]($SN))
}
elseif ($OP -eq '-') {
$solution = ([long]($FN) - [long]($SN))
}
elseif ($OP -eq '*') {
$solution = ([long]($FN) * [long]($SN))
}
elseif ($OP -eq '/') {
if ($SecondNumber -eq 0) {
$solution = "Cannot divide by 0";
}
$solution = ([long]($FN) / [long]($SN))
}
elseif ($OP -eq 'V') {
$solution = ([math]::Sqrt($FN))
}
else {
$solution = "Not a valid operator"
}
}
catch {
Write-Output "An error occured"
}
return $solution
Now this all works fine and when i go into the console and run it with ooutput going into a variable it works fine.
PS C:\PowerShellProject> $test = .\Script.ps1 1 1
PS C:\PowerShellProject> $test
2
But then when i run this Pester test
Describe "Test for Script.ps1" {
Context "Testing calculations" {
It " test" {
$plus = .\Test.ps1 -FN 2 -OP -SN 2
$plus | Should -Be 4
}
}
}
It returns the following
PS C:\PowerShellProject> Invoke-Pester .\Test.ps1
Starting discovery in 1 files.
Discovery found 1 tests in 15ms.
Running tests.
[-] Test for Script.ps1.Testing calculations. test 18ms (16ms|2ms)
Expected 4, but got $null.
at $plus | Should -Be 4, C:\PowerShellProject\Test.ps1:6
at <ScriptBlock>, C:\PowerShellProject\Test.ps1:6
[-] Context Test for Script.ps1.Testing calculations failed
InvalidOperationException: Collection was modified; enumeration operation may not execute.
Tests completed in 156ms
Tests Passed: 0, Failed: 1, Skipped: 0 NotRun: 1
BeforeAll \ AfterAll failed: 1
- Test for Script.ps1.Testing calculations
I'm still pretty new to Powershell so I must probably be making a silly mistake here.
Maybe someone could redirect me to another question that had a similar problem or give me a solution to my problem. This would be really helpful since I have been breaking my head over this for a couple of hours and it's really starting to annoy me.
CodePudding user response:
The problem is this line at the start of your function:
$solution
This does not declare the variable, as you propably expect, but due to PowerShells implicit output behaviour, it actually outputs the variable. The output is $null
as the variable has not been defined yet.
To actually define the variable you have to assign a value:
$solution = 0
Later, when you do return $solution
, you are actually adding another value to the output stream, which when captured to a variable, will be the array @($null, 2)
.
Proof:
$plus = .\Test.ps1 -FN 2 -OP -SN 2
Write-Host $plus.GetType().Name
This prints Object[]
, although we would expect int
.
In PowerShell you usually don't use the return
statement, except when you want to early exit from a function. return $solution
is actually just a shortcut for:
$solution # implicit output
return # exit from function
There is another issue in your Pester test script, where you are calling the wrong script. It should be:
$plus = .\Script.ps1 -FN 2 -OP -SN 2