Powershell 5类的Pester模拟方法

7

我在尝试模拟一个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"
    }
}
1个回答

6

我见过两种做法:

  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)。


是的,我考虑过那个解决方案,它可以工作,但我必须创建很多函数来测试我的类方法。哦,谢谢你的附注,我以为我做错了什么或者变得疯狂了。 - BenoitM
我听过(或被警告)多位PowerShell MVP说,PowerShell类是为支持基于类的DSC资源而创建的。否则使用PowerShell类会遇到一些问题,因为这种用法并不是PowerShell团队支持的重点。我正在使用PowerShell类进行面向对象编程,但在我的第一个项目中,我不得不编写大约10倍于生产代码的测试代码来了解事物的行为。 - alx9r
我在这里发布了许多测试。请查找提到“class”、“using”和“IEnumerable”的测试文件。我将为PowerShell类问题添加一个stackoverflow.com过滤器,以便如果您遇到更多困难,我可以看到您的问题。 - alx9r
@BenoitM 我添加了另一种方法来实现这个,我认为这更接近你所期望的。 - alx9r
我正在测试使用类来简化脚本中函数/库的可重用性和管理作用域。我不认为我需要很多OOP。我非常喜欢解决方案(2)。我会尝试在一个复杂的类中看看它是否会在测试脚本中增加太多负担,但它看起来不应该会这样。 - BenoitM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接