I would like to pass the key/values of a PowerShell hash to a Pester unit test, via the TestCases
parameter:
BeforeAll {
$Expected = @{
Address1='Address1'
Address2='Address2'
City='City'
RegionCode='RegionCode'
PostalCode='PostalCode'
}
}
BeforeEach {
Mock Invoke-SqlCmd
Invoke-MyFunction @Expected
}
It "sets the column '<Name>' with the value '<Value>'" -TestCases ( $Optional.GetEnumerator() | ForEach-Object { @{Name=$_.Key; Value=$_.Value} } ) {
param($Name, $Value)
$Test = "*{0}='{1}'*" -f $Name, $Value
Assert-MockCalled Invoke-Sqlcmd -ParameterFilter {
$Query -like $Test
}
}
But can't seem to get the hash's properties 'shaped' correctly to get the tests to work correctly.
Anything that you need to build the test cases needs to be in a BeforeDiscovery { ... }
block. The code in BeforeAll { ... }
gets deferred until execution of the tests, however your $expected
hashtable needs to be available earlier than that before discovery in order to build each of the tests from your test cases. In addition to that you need to nest your It { ... }
blocks in either a Describe
or Context
block
Update: per your comment - In order to make $Expected
available to the test scopes without duplicating the assignment in the BeforeEach block you can set the variable's scope to script scope
BeforeDiscovery {
$script:Expected = @{
Address1 = 'Value_Address1'
Address2 = 'Value_Address2'
City = 'Value_City'
RegionCode = 'Value_RegionCode'
PostalCode = 'Value_PostalCode'
}
}
Describe "Need a describe or context block" {
BeforeEach {
Mock Invoke-SqlCmd
Invoke-MyFunction @Expected
}
It "sets the column '<Name>' with the value '<Value>'" -TestCases (
$Expected.GetEnumerator() |
ForEach-Object { @{Name = $_.Key; Value = $_.Value } }
) {
# param($Name, $Value)
$Test = "*{0}='{1}'*" -f $Name, $Value
# Assert-MockCalled Invoke-Sqlcmd -ParameterFilter {
# $Query -like $Test
# }
}
}
Output
Pester v5.3.1
Starting discovery in 1 files.
Discovery found 5 tests in 25ms.
Running tests.
Running tests from 'C:\temp\powershell\pester.tests.ps1'
Describing Need a describe or context block
[+] sets the column 'RegionCode' with the value 'Value_RegionCode' 8ms (4ms|4ms)
[+] sets the column 'City' with the value 'Value_City' 2ms (1ms|1ms)
[+] sets the column 'Address2' with the value 'Value_Address2' 5ms (1ms|3ms)
[+] sets the column 'PostalCode' with the value 'Value_PostalCode' 3ms (1ms|2ms)
[+] sets the column 'Address1' with the value 'Value_Address1' 3ms (1ms|2ms)
Tests completed in 168ms
Tests Passed: 5, Failed: 0, Skipped: 0 NotRun: 0
See Pester's v5 Discovery and Run docs
Paraphrased from that page:
This is what happens during the initial Discovery phase when you run Invoke-Pester
BeforeAll
function runs ONLY saving the scriptblock provided to it, not executing it (yet) Hashtable and other variables inside this block have not been created yetDescribe
function runs AND invokes the scriptblock provided to it in order to collect information about the tests contained inside it. Note: Describe
and Context
scriptblocks are the only scriptblocks that are run during discovery-TestCases
) that are provided to the It
function are evaluated by PowerShell (this is where the hashtable is needed however sadly it hasn't been brought into existence yet)It
function runs saving (NOT running) the code contained generating the tests, 1 per each item in the previously evaluated -TestCases
arrayWrite-Host "Discovery done."
is run.