3

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. 私は、(モックしようとしている) SQL 関数が定義されているモジュールではなく、 Main-Functionが定義され-ModuleNameているモジュールに設定する必要があることを観察/解決しました。
  3. 私はInModuleScopeandをいじってみました。-ModuleNameたとえば、一方または他方をModuleSQLに設定しましたが、主にそれが事態を悪化させました。

遊んで、他のモック関数に詳細出力を追加することで、New-SqlConnectionClose-SqlConnectionの両方が傍受されていることを確認しましたが、Invoke-SqlStoredProcとはそうでInvoke-SqlQueryはありません。

Invoke-Sql*さらに詳しく調べてみると、 (モックされた) 関数によって次の例外がスローされていることがわかりますこれ、これらの関数の実際のバージョンが呼び出されたときに予想される動作ですが、モックされたバージョンではパラメーターの型が無視されることを期待しています。

Pester が私の 4 つの機能のうち 2 つしかインターセプトしないのはなぜですか?

4

1 に答える 1

4

したがって、この質問に対する短い答えは、上記のコメントに記載されています。

モック関数はパラメーターの型を無視しません。--PetSerAl

Invoke-Sql*これは、関数を呼び出そうとしたときに、偽の$sqlConnection変数 (単純に$trueに設定) を使用すると、入力パラメーターが予期されたデータ型ではなかったため、エラーが発生したことを意味していました。

私の場合の解決策は、関数をモックしてオブジェクトNew-SqlConnectionを返すことでした。たまたま、各モックでモジュールを指定するのではなく、[System.Data.SqlCient.SqlConnection]使用するように戻しました。InModuleScope

InModuleScope "ModuleMain" {
  Describe "MainFunction" {

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

    ...
}
于 2016-03-21T13:11:49.243 に答える