I'm trying to do a simple parallel operation in Powershell. I am using PoshRSJobs for multithreading, though I have also tried Invoke-Parallel with the same issue. I need to call a couple of my own functions in the scriptbody of the job, but this does not allow me to MOCK those functions for unit testing (they end up being the original non-mocked functions). At this point, I'm just trying to assert that they have been called the correct number of times.
Here is the original class (the functionality of the imported modules are irrelevant - the actual implementations are currently returning test strings)...
Import-Module $PSScriptRoot\Convert-DataTable
Import-Module $PSScriptRoot\Get-History
Import-Module $PSScriptRoot\Get-Assets
Import-Module $PSScriptRoot\Write-DataTable
function MyStuff (
param(
[string]$serverInstance = "localhost\SQLEXPRESS",
[string]$database = "PTLPowerShell",
[string]$tableName = "Test"
)
$assets = Get-Assets
$full_dt = New-Object System.Data.DataTable
$assets | Start-RSJob -ModulesToImport $PSScriptRoot\Convert-FLToDataTable, $PSScriptRoot\Get-FLHistory {
$history = Get-History $asset
$history_dt = Convert-DataTable $history
return $history_dt.Rows
} | Wait-RSJob | Receive-RSJob | ForEach {
$full_dt.Rows.Add($_)
}
Write-DataTable $serverInstance $database $tableName $full_dt
}
Here is the Pester test...
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"
Describe "MyStuff" {
BeforeEach {
Mock Get-Assets { return "page1", "page2"}
Mock Get-History { return "history" }
Mock Convert-DataTable {
$historyDT = New-Object System.Data.Datatable;
$historyDT.TableName = 'Test'
return ,$historyDT
}
Mock Write-DataTable {}
}
It "should do something" {
{ MyStuff } | Should -Not -Throw;
}
It "should call Get-FLAssetGrid" {
Assert-MockCalled Get-Assets 1
}
It "should call Get-FLHistory" {
Assert-MockCalled Get-History 2
}
It "should call Convert-DataTable" {
Assert-MockCalled Convert-DataTable 2
}
It "should call Write-DataTable" {
Assert-MockCalled Write-DataTable 1
}
}
Here is the Pester test's output currently...
Describing MyStuff
[+] should do something 1.71s
[+] should call Get-Assets 211ms
[-] should call Get-History 61ms
Expected Get-History to be called at least 2 times but was called 0 times
23: Assert-MockCalled Get-History 2
at <ScriptBlock>, myFile.Tests.ps1: line 23
[-] should call Convert-DataTable 110ms
Expected Convert-DataTable to be called at least 2 times but was called 0 times
26: Assert-MockCalled Convert-DataTable 2
at <ScriptBlock>, myFile.Tests.ps1: line 26
[+] should call Write-DataTable 91ms
So ultimately, I'm looking for a way to do parallel operations in PowerShell and still be able to mock and unit test them.