multithreading - 如何使用 PowerShell 多线程以及 Pester Mocks 进行单元测试

标签 multithreading powershell mocking pester

我正在尝试在 Powershell 中执行简单的并行操作。我正在使用 PoshRSJobs 进行多线程处理,尽管我也尝试过 Invoke-Parallel 来解决同样的问题。 我需要在作业的脚本主体中调用几个我自己的函数,但这不允许我模拟这些函数以进行单元测试(它们最终成为原始的非模拟函数)。此时,我只是想断言它们被调用的次数是正确的。

这是原始类(导入模块的功能无关 - 实际实现当前返回测试字符串)...

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
}

这是 Pester 测试...

$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
    }
}

这是当前 Pester 测试的输出...

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

所以最终,我正在寻找一种在 PowerShell 中执行并行操作并且仍然能够模拟和单元测试它们的方法。

最佳答案

我不认为这是一个完整的答案,而且我也不参与 Pester 项目,但我想说这根本不是 Pester 支持的场景。当/如果 concurrent programming becomes part of PowerShell proper 时,这可能会改变(或者可能不会)。

如果您愿意更改您的实现,您也许可以围绕此限制进行编写以支持某种测试。

例如,当您的函数只有一件事要做时,也许您的函数不使用 RSJob(测试时可能会出现这种情况)。

或者也许您实现了 -Serial-NoParallel-SingleRunspace 开关(或 -ConcurrencyFactor在测试中将其设置为 1),其中您不会针对这些条件使用运行空间。

根据您的示例,很难判断这种测试是否充分测试了您想要的内容,但看起来确实如此。

关于multithreading - 如何使用 PowerShell 多线程以及 Pester Mocks 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47913985/

相关文章:

.net - WinForms : Implementation question for having my UI run independently of my BLL layer?

java - 线程转储: What to look for to determine the thread responsible for 100% CPU?

unit-testing - Spock模拟返回错误值

powershell - 在双引号内插时PowerShell输出数组项

python - 如何在不运行 CLIrunner.invoke() 的情况下将输入传递给 click.confirm

ios - 未观察到 OCMock 预期的通知

java - 使用共享对象实例化多个 Runnable 的含义是什么?

c++ - 在对其进行线程操作后保存 GDI+ 位图

windows -/ChainingPackage 做什么?

windows - 当进程不存在时如何使用powershell杀死进程而不会出错