gpt4 book ai didi

powershell - Mock 函数应该如何接受 Pester 中的管道输入?

转载 作者:行者123 更新时间:2023-12-02 01:17:35 35 4
gpt4 key购买 nike

我是 Pester 的新手,我正在尝试在 PowerShell 中为一个非常小且简单的函数构建测试:

function Toggle-Notepad {
if (-not ( Get-Process notepad -ErrorAction SilentlyContinue ) )
{
Start-Process -FilePath Notepad
}
else
{
get-process notepad | stop-process
}

}

如果记事本没有运行,这个函数只会启动它,如果它正在运行,它就会停止它。

我设计的测试是这样的:

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"

Describe "Toggle-Notepad" {
Mock Stop-Process { "Process object passed! Stopping notepad!" }
Mock Start-Process { "Notepad is not running,starting it!" } -ParameterFilter { $Filepath -eq "Notepad" }

It "Starts notepad if it is not running" {
Toggle-Notepad | Should be "Notepad is not running,starting it!"
}

It "Stops notepad if it is running" {
Toggle-Notepad | Should be "Process object passed ! Stopping notepad!"
}
}

以上测试按预期运行。

如何重写 Stop-Process 函数,以便指定此版本用于接受管道输入?

我试过了,但是没用:

$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut"

Describe "Toggle-Notepad" {
Mock stop-process { "Process object passed ! Stopping notepad" } -ParameterFilter { $InputObject -is "System.Diagnostics.Process" }
Mock Start-Process {"Notepad is not running,starting it!"} -ParameterFilter { $Filepath -eq "Notepad" }

It "Starts notepad if it is not running" {
Toggle-Notepad | Should be "Notepad is not running,starting it!"
}

It "Stops notepad if it is running" {
Toggle-Notepad | Should be "Process object passed ! Stopping notepad!"
}
}

由于 Stop-Process 函数正在接受管道输入,我的目标是模拟与此类似的函数,而不是创建一个不接受任何参数的通用 Stop-Process 函数.

有没有 Pester 专家可以提供帮助?

最佳答案

您通常不需要在 Mock 中手动定义参数,因为被模拟的函数的参数是在 Mock 中自动创建的。

你的 Stop-Process Mock 不工作的原因是你用 -ParameterFilter 属性定义了它,这导致它只在定义的参数时被调用是真的。您的过滤器不起作用,因为您将对象类型引用为字符串 ("System.Diagnostics.Process") 而不是类型(用方括号声明)。

Mock 的正确代码是:

Mock stop-process { "Process object passed ! Stopping notepad!" } -ParameterFilter { $InputObject -is [System.Diagnostics.Process[]] }

asked this question of the Pester development team directly他们提出了一个更简单的解决方案,即 -ParameterFilter { $InputObject },因为如果没有填充该类型的有效对象,它将为 null。

这是一个完整的例子:

Describe 'Mocking stop-process' {

Mock Stop-Process {
Write-Host "Mock stopping: $InputObject"
} -ParameterFilter { $InputObject }

It 'Should mock stopping the notepad process' {
Get-Process notepad | Stop-Process | Should Be $null
}

}

另外仅供引用,自 Pester 3.4.4 以来,现在有一个 New-MockObject允许您创建任何类型的假对象的命令:

New-MockObject is a Pester function (introduced in Pester 3.4.4) that allows you to create "fake" objects of almost any type to run in Pester mocks. These "fake objects" allow your mocks to return the same type as the function it was mocking to pass the result to entities that are strongly typed.

在您的场景中没有必要,但我认为您可能会发现它相关/有趣。

关于powershell - Mock 函数应该如何接受 Pester 中的管道输入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41892907/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com