2

我正在尝试为我的 Azure 自动化运行手册编写 Pester 测试。Runbook 脚本使用Get-AutomationVariablecmdlet,我试图通过以下方式模拟它:

mock 'Get-AutomationVariable' {return "localhost:44300"} -ParameterFilter { $name -eq "host"}

导致错误

CommandNotFoundException:术语“Get-AutomationVariable”未被识别为 cmdlet、函数、脚本文件或可运行程序的名称。

检查名称的拼写,或者如果包含路径,请验证路径是否正确并重试。

-ModuleName参数的使用似乎不合适,因为我是从脚本而不是模块调用该方法。尝试提供存根模块会导致抛出相同的错误。

. "$here\$sut" "CN=teset, OU=Test" "CN=SubCA02, OU=Test"

Get-Module -Name RunbookMock | Remove-Module
New-Module -Name RunbookMock -ScriptBlock {
  function Get-AutomationVariable {
    [CmdLetBinding()]
    param(
      [string]$Name
    )

    ""
  }
  Export-ModuleMember Get-AutomationVariable
} | Import-Module -Force

describe 'Pin-Certificate' {
  it 'should add an entry to the pinned certificate list'{
    mock 'Get-AutomationVariable' { return "sastoken"} -ParameterFilter {  $Name -eq "StorageSasToken"} -
    mock 'Get-AutomationVariable' {return "localhost:44300"} -ParameterFilter { $name -eq "host"}
  }
}
4

2 回答 2

3

根据评论,您的代码应该可以工作。过去我只是声明了一个空函数而不是一个完整的模块。例如:

function MyScript {
    Get-FakeFunction
}

Describe 'Some Tests' {

    function Get-Fakefunction {}

    Mock 'Get-Fakefunction' { write-output 'someresult' }

    $Result = MyScript

    it 'should invoke Get-FakeFunction'{
        Assert-MockCalled 'Get-Fakefunction' -Times 1              
    }
    it 'should return someresult'{
        $Result | Should -Be 'someresult'
    }
}
于 2018-05-04T14:28:42.177 回答
2

核心问题是陈述的顺序。被测脚本是在模拟声明之前获取的。重新排序语句以声明模拟然后源脚本解决了问题,@MarkWragg 的出色建议有助于进一步简化代码。其最终工作状态如下。

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

  function Get-AutomationVariable {
    [CmdLetBinding()]
    param([string]$Name)
  }

describe 'Pin-Certificate' {
  it 'should add an entry to the pinned certificate list' {
    mock 'Get-AutomationVariable' -MockWith { "sastoken" } -ParameterFilter {  $Name -eq "StorageSasToken"}
    mock 'Get-AutomationVariable' -MockWith { "localhost:44300" } -ParameterFilter { $Name -eq "host"}
    mock 'Invoke-WebRequest' -MockWith { @{ "StatusCode" = "204"; }   }

    # dot source the sut, invoking the default function
    $result = (. "$here\$sut" "Subject" "Issuer" "Thumbprint")

    $result.Issuer | Should be "Issuer"
    $result.Subject | Should Be "Subject"
    $result.Thumbprint | Should Be "Thumbprint"
  }
于 2018-05-04T14:26:51.610 回答