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.
CodePudding user response:
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
- Test script file is invoked
BeforeAllfunction runs ONLY saving the scriptblock provided to it, not executing it (yet) Hashtable and other variables inside this block have not been created yetDescribefunction runs AND invokes the scriptblock provided to it in order to collect information about the tests contained inside it. Note:DescribeandContextscriptblocks are the only scriptblocks that are run during discovery- All parameters (including
-TestCases) that are provided to theItfunction are evaluated by PowerShell (this is where the hashtable is needed however sadly it hasn't been brought into existence yet) Itfunction runs saving (NOT running) the code contained generating the tests, 1 per each item in the previously evaluated-TestCasesarrayWrite-Host "Discovery done."is run.
