[英]Synchronous unit test execution in Powershell
I've got a Pester It block, that looks like the below:我有一个 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 just updates a file with some new text. Set-PowershellFile 只是用一些新文本更新文件。 I thought that the above code would do the following but I just want to confirm:
我认为上面的代码会执行以下操作,但我只想确认:
Is this correct?这个对吗? When I run my unit tests, the file change made in Set-PowershellFile does not persist, but the unit test passes.
当我运行单元测试时,在 Set-PowershellFile 中所做的文件更改不会持续存在,但单元测试通过了。 I assumed that wrapping this code inside the if block in {} causes the synchronous behavior but doesn't 'commit' the file changes.
我假设将此代码包装在 {} 中的 if 块中会导致同步行为,但不会“提交”文件更改。 Is this all correct?
这一切都正确吗?
Mathias R.马蒂亚斯 R。 Jessen provided the crucial pointer in a comment - simply omit the inner
{
and }
- but since I've seen the underlying misconception before, it's worth digging deeper: Jessen在评论中提供了关键指针 - 只需省略内部
{
和}
- 但由于我之前已经看到了潜在的误解,因此值得深入挖掘:
While {... }
blocks are a regular part of most PowerShell statements, such as foreach
and if
, in isolation they do not provide a scoped block of statements that are immediately executed , the way it would work in C#, for instance.虽然
{... }
块是大多数 PowerShell 语句的常规部分,例如foreach
和if
,但它们不提供立即执行的范围语句块,例如它在C#中的工作方式。
Instead, {... }
in isolation is the literal form of a PowerShell script block , ie a block of statements for later execution, on demand , either via &
, the call operator , for execution in a child scope of , or via .
相反,
{... }
孤立地是 PowerShell 脚本块的文字形式,即稍后执行的语句块,根据需要,通过&
, 调用运算符,在子 scope 中执行,或通过.
, the dot-sourcing operator , for execution directly in the scope of origin - which may or may not be the caller's scope (see caveat below). , 点源运算符,直接在原点 scope 中执行 - 这可能是也可能不是调用者的scope(请参阅下面的警告)。
Thus, such a script-block literal must either be saved in a variable or passed to a command expecting a script block in order to be executed later .因此,这样的脚本块文字必须要么保存在变量中,要么传递给需要脚本块的命令,以便稍后执行。
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, excluding the delimiters ( {
and }
). 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,不包括分隔符( {
和}
)。
For instance:例如:
# Script block literal is output by its *verbatim content* (without delimiters)
PS> { "Honey, I'm $HOME" }
"Honey, I'm $HOME"
In order to use a script block properly, you must execute it , typically with &
:为了正确使用脚本块,您必须执行它,通常使用
&
:
# `& ` 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.
Caveat :警告:
Script-block literals - unlike script blocks constructed with [scriptblock]::Create('...')
- are tied to the scope domain (aka "session state") in which they are defined .脚本块文字- 与使用
[scriptblock]::Create('...')
构建的脚本块不同 - 与定义它们的 scope 域(又名“会话状态”)相关联。
This means:这表示:
Script-block literals defined outside a module , when also called from outside a module, do run in a child scope of ( &
) / directly in ( .
) the caller's 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 thereof (with &
). 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其中(带&
)。
Examples:例子:
PS> $foo = 1; function Get-ScriptBlock { { (++$foo) } }; . (Get-ScriptBlock)
2
That is, the script block created in the non-module scope domain invoked with .
即,在非模块 scope 域中创建的脚本块使用
.
ran directly in the non-module caller's scope.直接在非模块调用者的 scope 中运行。
PS> $foo = 1; $null = New-Module { $foo = 99; function Get-ScriptBlock { { (++$foo) } } }; . (Get-ScriptBlock)
100
That is, the script block created in the scope domain of the dynamic module created with New-Module
, invoked with .
也就是说,在使用
New-Module
创建的动态模块的 scope 域中创建的脚本块,使用 调用.
, ran in that module's top-level scope, even though it was invoked from a non-module caller. ,在该模块的顶级 scope 中运行,即使它是从非模块调用者调用的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.