簡體   English   中英

Pester:並非所有模擬函數都被攔截

[英]Pester: not all mocked functions are intercepted

我有許多模塊,包括ModuleMainModuleSql 模塊之間存在相互依賴關系,因此 ModuleMain 中的Main-Function使用 ModuleSql 中的 4 個函數:

function Main-Function {
  [CmdletBinding(SupportsShouldProcess=$true)]

  # The following 4 lines are all wrapped in $PSCmdlet.ShouldProcess() and
  # try {} catch {} logic. I have left that out in this post, but I mention
  # it in case it is relevant.

  $a = New-SqlConnection
  $b = Invoke-SqlStoredProc -connection $a
  $c = Invoke-SqlQuery -connection $a
  Close-SqlConnection -connection $a | Out-Null
  return $c
}

我創建了一個Function-Main1.tests.ps1文件來測試 Function-Main1。 起初我使用InModuleScope但后來切換到使用-ModuleName參數指定每個模擬的模塊。

Import-Module "ModuleMain" -Force

Describe "Main-Function" {

  Mock -ModuleName ModuleMain New-SqlConnection {
    return $true }
  Mock -ModuleName ModuleMain Invoke-SqlStoredProc {
    return $true }
  Mock -ModuleName ModuleMain Invoke-SqlQuery {
    return $true }
  Mock -ModuleName ModuleMain Close-SqlConnection {
    return $true }

  Context "When calling Main-Function with mocked SQL functions" {
    It "Calls each SQL function once" {
      Assert-MockCalled -Scope Context -ModuleName ModuleMain -CommandName New-SqlConnecion -Times 1 -Exactly
      Assert-MockCalled -Scope Context -ModuleName ModuleMain -CommandName Invoke-SqlStoredProc -Times 1 -Exactly
      Assert-MockCalled -Scope Context -ModuleName ModuleMain -CommandName Invoke-SqlQuery -Times 1 -Exactly
      Assert-MockCalled -Scope Context -ModuleName ModuleMain -CommandName Close-SqlConnecion -Times 1 -Exactly
    }
  }
}

當我運行這個測試時,我得到以下結果:

[-] Calls each SQL function once 223ms
  Expected Invoke-SqlStoredProc in module ModuleMain to be called 1 times exactly but was called 0 times
  at line: xx in 
  xx:       Assert-MockCalled -Scope Context -ModuleName ModuleMain -CommandName Invoke-SqlStoredProc -Times 1 -Exactly

請注意以下事項:

  1. 我沒有導入定義了-Sql函數的ModuleSql ,因為無論如何我都在嘲笑它們。
  2. 我已經觀察/計算出我需要將-ModuleName設置為定義Main-Function的模塊,而不是定義 SQL 函數(我試圖模擬的)的模塊。
  3. 我玩過InModuleScope-ModuleName ,例如將一個或另一個設置為ModuleSQL ,但主要是這讓事情變得更糟。

通過在其他模擬函數中添加 Verbose 輸出,我確認New-SqlConnectionClose-SqlConnection都被攔截,但Invoke-SqlStoredProcInvoke-SqlQuery沒有被攔截。

深入探究,我可以看到Invoke-Sql*Invoke-Sql* )函數拋出以下異常:錯誤:“從 'System.Boolean' 到 'System.Data.SqlClient.SqlConnection' 的無效轉換。” 我在調用這些函數的真實版本時所期望的行為,但我期望模擬版本會忽略參數類型。

為什么 Pester 只會攔截我的 4 個函數中的 2 個?

因此,在上面的評論中給出了對這個問題的簡短回答:

模擬函數不會忽略參數類型。 --寵物系列

這意味着當我嘗試調用Invoke-Sql*函數並使用虛假的$sqlConnection變量(簡單地設置為$true )時,這會導致錯誤,因為輸入參數不是預期的數據類型。

在我的情況下,解決方案是模擬New-SqlConnection函數,因此它返回一個[System.Data.SqlCient.SqlConnection]對象。 碰巧的是,我也恢復使用InModuleScope而不是在每個 Mock 上指定模塊:

InModuleScope "ModuleMain" {
  Describe "MainFunction" {

    Mock New-SqlConnection {
      New-Object -TypeName System.Data.SqlCient.SqlConnection
    }

    ...
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM