6

テストを実行すると、「 CommandNotFoundException: Command FunctionToMock が見つかりませんでした」というエラーが表示されます。「FunctionToMock」をモックして、「OutputToOverwrite」メソッドを単体テストしようとしています。最初に ChocoClass 自体をモックする必要があると思いますが、その方法がわかりません。ありがとう。

Class ChocoClass
{
    [string] OutputToOverwrite()
    {
        return $this.FunctionToMock()
    }

    [string] FunctionToMock()
    {
        return "This text will be replaced"
    }
}


Describe "Testing mocking"{
    it "Mock test"{
        Mock FunctionToMock -MockWith {return "mystring"}
        $package = New-Object ChocoClass
        $expected = $package.OutputToOverwrite()
        $expected | should BeExactly "mystring"
    }
}
4

1 に答える 1

5

これを行うには、次の 2 つの方法を見てきました。

  1. 実装の大部分を関数に分割します。
  2. クラスから継承し、メソッドをオーバーライドします。

(1) 関数を使う

メソッドの実装を次のような関数に分けています。

Class ChocoClass
{
    [string] OutputToOverwrite()
    {
        return $this.FunctionToMock()
    }

    [string] FunctionToMock()
    {
        return FunctionToMock $this
    }
}

function FunctionToMock
{
    param($Object)
    return "This text will be replaced"
}

その変更により、あなたのテストは私のコンピューターで成功します。これにより、PowerShell クラス関連の落とし穴が回避されますが、クラスの動作のテストも回避されます。

(2) メソッドの派生とオーバーライド

クラスを派生させ、モックするメソッドをオーバーライドできます。

Describe "Testing mocking"{
    it "Mock test"{
        class Mock : ChocoClass {
            [string] FunctionToMock() { return "mystring" }
        }
        $package = New-Object Mock
        $expected = $package.OutputToOverwrite()
        $expected | should BeExactly "mystring"
    }
}

このテストは私のコンピューターで成功しました。私はまだこの方法を製品コードに使用したことはありませんが、この方法がいかに直接的であるかが気に入っています。単一の PowerShell セッションで同じ名前のクラスを再定義することに関連する問題に注意してください (以下の補足事項を参照)。


補足: (1) を分離することで、クラスに変更を加えたときにクラスがリロードされなくなるというこのバグに遭遇する量が最小限に抑えられます。ただし、より良い回避策は、新しい PowerShell セッション (例: PS C:\>powershell.exe -Command { Invoke-Pester }) で各テスト実行を呼び出すことであることがわかったため、現在は (2) に傾いています。

于 2017-03-01T00:12:18.053 に答える