当我尝试让这个 pester 测试为接收管道参数的函数工作时,收到以下错误。
“运行 Pester 时发生错误:输入对象无法绑定到该命令的任何参数,因为该命令不接受管道输入,或者输入及其属性与任何接受管道输入的参数不匹配。”
模块:MyModule.psm1
function MyFunction {
"piping to Write-Output" | Write-Output
$dataTable = New-Object System.Data.DataTable
$dataTable | MyPipelineFunction
}
function MyPipelineFunction {
[CmdletBinding()]
param (
[Parameter(
Mandatory = $true,
ValueFromPipeline=$true)]
[System.Data.DataTable] $DataTable
)
Write-Host "hello world"
}
骚扰测试
Import-Module "C:\temp\StackOverflow\PipelineMock\MyModule\MyModule.psm1" -Force
InModuleScope 'MyModule' {
Describe 'MyFunction' {
BeforeAll {
# Create a sample DataTable
$dataTable = New-Object System.Data.DataTable
$dataTable.Columns.Add("Column1", [System.String])
$row = $dataTable.NewRow()
$row["Column1"] = "Sample Data"
$dataTable.Rows.Add($row)
# Mock the DataTable creation in MyInternalFunction
Mock -CommandName New-Object -ParameterFilter { $TypeName -eq 'System.Data.DataTable' } -MockWith { return $dataTable }
Mock MyPipelineFunction -MockWith {[CmdletBinding()] param (
[Parameter(
Mandatory = $true,
ValueFromPipeline=$true)]
[System.Data.DataTable] $DataTable
)
}
Mock Write-Output {}
}
It 'should call MyPipelineFunction' {
MyFunction
Assert-MockCalled -CommandName Write-Output -Exactly 1 -Scope It
Assert-MockCalled -CommandName New-Object -Exactly 1 -Scope It -ParameterFilter {$TypeName -eq 'System.Data.DataTable' }
Assert-MockCalled -CommandName MyPipelineFunction -Exactly 1 -Scope It -ParameterFilter {$DataTable -eq $dataTable}
}
}
}
根据我找到的信息,我有几个不同的 Mock 方法和参数过滤器。Pester 网站似乎没有对此提供任何明确的指导。我能够为 Write-Output 编写一个基本的模拟,我将文本传输到它,效果很好。
有人能看出这个问题吗?
请注意
Assert-MockCalled
已过时,替代的是Should -Invoke
。有关详细信息,请参阅文档。在向您展示 Pester 代码的外观之前,您必须了解以下三件事:
Mathias在他的评论中提到,即使
DataTable
不是IEnumerable
管道也会枚举它,本质上是通过枚举DataRowCollection
,参见Binders.cs#L613-L638
。因此,如果您想要管道它,并且您的函数要按原样接收它,您必须使用Write-Output -NoEnumerate
或,
运算符:在您的通话中也会应用相同的考虑
Mock -CommandName New-Object
,您必须-MockWith { , $dataTable }
在那里使用(注意,
变量之前)。管道中提到的这种枚举行为也适用于 Pester 调用
-MockWith
脚本块时,从而枚举其输出,直观地讲:您不应该在脚本块
param
中定义块-MockWith
,如文档中所建议的那样:您断言的是
{ $DataTable -eq $dataTable }
,您应该注意 PowerShell 是一种不区分大小写的语言,$DataTable
并且$dataTable
在这种情况下引用相同的变量。此外,使用-eq
运算符的相等比较无法判断用作函数参数的 DataTable 和BeforeAll
块中创建的 DataTable 是否相同。在这种情况下,您可以使用[object]::ReferenceEquals
,但是您需要在测试中使用不同的变量名。综上所述,Pester 测试应该解决的问题: