【问题标题】:Pester mock method for Powershell 5 classPowershell 5 类的 Pester 模拟方法
【发布时间】:2017-02-28 16:10:21
【问题描述】:

我在尝试模拟 powershell 5 类方法时遇到问题,在执行测试时,我收到错误“CommandNotFoundException:找不到命令 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"
    }
}

【问题讨论】:

    标签: class powershell pester


    【解决方案1】:

    我见过两种方法:

    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) 的分离使我遇到this bug that prevents classes from being reloaded when you make changes to them 的数量最小化。不过,我发现更好的解决方法是在新的 PowerShell 会话中调用每个测试运行(例如 PS C:\>powershell.exe -Command { Invoke-Pester }),所以我现在倾向于 (2)。

    【讨论】:

    • 是的,我考虑过那个可行的解决方案,但我必须创建很多函数来测试我的类方法。哦,谢谢你的旁注,我以为我做错了什么或发疯了。
    • 我从不止一个 PowerShell MVP 那里听说(或被警告过),创建 PowerShell 类是为了支持基于类的 DSC 资源。否则,使用 PowerShell 类意味着您将遇到困难,因为这种使用并不是 PowerShell 团队支持的优先事项。我正在为 OOP 使用 PowerShell 类,但在我的第一个这样的项目中,我必须编写大约 10 倍于类的生产代码的测试代码才能弄清楚事情的表现。
    • 我发布了许多测试here。查找提及“class”、“using”和“IEnumerable”的测试文件。我将为 PowerShell 类问题添加一个 stackoverflow.com 过滤器,因此如果您遇到更粗糙的问题,我会看到您的过滤器。
    • @BenoitM 我添加了另一种方法来做到这一点,我认为更接近您的期望。
    • 我正在测试类的使用,以简化脚本中函数/库的可重用性并管理范围。我认为我不需要太多的 OOP。我真的很喜欢解决方案(2)。我将尝试在一个复杂的类中查看它是否会在测试脚本中增加很多臃肿,但它看起来不应该。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多