[英]Synchronous unit test execution in Powershell
我有一个 Pester It 块,如下所示:
It "should add a header" {
{
$DifferenceObject = Get-Content -Path $PathToFile1
Set-PowershellFile -Path $PathToFile2
$ReferencedObject = Get-Content -Path $PathToFile2
Compare-Object -ReferenceObject $ReferencedObject -DifferenceObject $DifferenceObject | should -be $null
}
}
Set-PowershellFile 只是用一些新文本更新文件。 我认为上面的代码会执行以下操作,但我只想确认:
这个对吗? 当我运行单元测试时,在 Set-PowershellFile 中所做的文件更改不会持续存在,但单元测试通过了。 我假设将此代码包装在 {} 中的 if 块中会导致同步行为,但不会“提交”文件更改。 这一切都正确吗?
马蒂亚斯 R。 Jessen在评论中提供了关键指针 - 只需省略内部{
和}
- 但由于我之前已经看到了潜在的误解,因此值得深入挖掘:
虽然{... }
块是大多数 PowerShell 语句的常规部分,例如foreach
和if
,但它们不提供立即执行的范围语句块,例如它在C#中的工作方式。
相反, {... }
孤立地是 PowerShell 脚本块的文字形式,即稍后执行的语句块,根据需要,通过&
, 调用运算符,在子 scope 中执行,或通过.
, 点源运算符,直接在原点 scope 中执行 - 这可能是也可能不是调用者的scope(请参阅下面的警告)。
因此,这样的脚本块文字必须要么保存在变量中,要么传递给需要脚本块的命令,以便稍后执行。
Absent that, a script block is implicitly output to the success output stream , which by default goes to the console (host), causing it to be rendered by its .ToString()
value, which is simply the verbatim content of the script block,不包括分隔符( {
和}
)。
例如:
# Script block literal is output by its *verbatim content* (without delimiters)
PS> { "Honey, I'm $HOME" }
"Honey, I'm $HOME"
为了正确使用脚本块,您必须执行它,通常使用&
:
# `& ` executes in a child scope of and
# `. ` executes directly in the scope of origin, typically the current scope.
PS> & { "Honey, I'm $HOME" }
Honey, I'm C:\Users\jdoe # e.g.
警告:
脚本块文字- 与使用[scriptblock]::Create('...')
构建的脚本块不同 - 与定义它们的 scope 域(又名“会话状态”)相关联。
这表示:
在模块外部定义的脚本块文字,当也从模块外部调用时,确实在 ( &
) 的子 scope 中运行/直接在 ( .
)调用者的scope 中运行。
By contrast, script-block literals defined inside a module , are tied to that module's scope domain , meaning that an invocation - irrespective of where the call is made from - execute in that module's top-level scope (with .
) or a child scope其中(带&
)。
例子:
PS> $foo = 1; function Get-ScriptBlock { { (++$foo) } }; . (Get-ScriptBlock)
2
即,在非模块 scope 域中创建的脚本块使用.
直接在非模块调用者的 scope 中运行。
PS> $foo = 1; $null = New-Module { $foo = 99; function Get-ScriptBlock { { (++$foo) } } }; . (Get-ScriptBlock)
100
也就是说,在使用New-Module
创建的动态模块的 scope 域中创建的脚本块,使用 调用.
,在该模块的顶级 scope 中运行,即使它是从非模块调用者调用的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.