繁体   English   中英

Powershell 中的同步单元测试执行

[英]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 只是用一些新文本更新文件。 我认为上面的代码会执行以下操作,但我只想确认:

  1. 它获取位于“PathToFile1”的文件的内容
  2. 它使用 Set-PowershellFile 将文件设置为“PathToFile2”,然后获取该文件的新内容。
  3. 将新更新的文件与第一个文件的内容进行比较,确保它们相同。

这个对吗? 当我运行单元测试时,在 Set-PowershellFile 中所做的文件更改不会持续存在,但单元测试通过了。 我假设将此代码包装在 {} 中的 if 块中会导致同步行为,但不会“提交”文件更改。 这一切都正确吗?

马蒂亚斯 R。 Jessen在评论中提供了关键指针 - 只需省略内部{} - 但由于我之前已经看到了潜在的误解,因此值得深入挖掘:

虽然{... }块是大多数 PowerShell 语句的常规部分,例如foreachif ,但它们提供立即执行的范围语句块,例如它在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM