如何使用PowerShell多线程并使用Pester Mocks进行单元测试

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何使用PowerShell多线程并使用Pester Mocks进行单元测试相关的知识,希望对你有一定的参考价值。

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

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

Import-Module $PSScriptRootConvert-DataTable
Import-Module $PSScriptRootGet-History
Import-Module $PSScriptRootGet-Assets
Import-Module $PSScriptRootWrite-DataTable

function MyStuff (
    param(
        [string]$serverInstance = "localhostSQLEXPRESS", 
        [string]$database = "PTLPowerShell",
        [string]$tableName = "Test"
    )
    $assets = Get-Assets
    $full_dt = New-Object System.Data.DataTable
    $assets | Start-RSJob -ModulesToImport $PSScriptRootConvert-FLToDataTable, $PSScriptRootGet-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开关(或者你在测试中设置为-ConcurrencyFactor1),其中你不使用运行空间来满足这些条件。

根据你的例子,很难判断这种测试是否能够充分测试你想要的东西,但看起来确实如此。

以上是关于如何使用PowerShell多线程并使用Pester Mocks进行单元测试的主要内容,如果未能解决你的问题,请参考以下文章

发布支持多线程的PowerShell模块 —— MultiThreadTaskRunner

powershell 使用FAF技术(批量数据集和内联多线程)快速CSV到SQL Server导入

Powershell 多线程数学

Powershell 之多线程监控网页状态

powershell Windows上的多线程大文件夹删除

如何使用多线程优化多查询复杂业务接口,并保证线程安全