Powershell 5 的 Pester 模拟方法 class
Pester mock method for Powershell 5 class
我在尝试模拟 powershell 5 class 方法时遇到问题,在执行测试时,我收到错误“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"
}
}
我见过两种方法:
- 将大部分实现分离到一个函数中。
- 继承自 class 并覆盖该方法。
(1) 使用函数
我一直将方法的实现分离成这样的函数:
Class ChocoClass
{
[string] OutputToOverwrite()
{
return $this.FunctionToMock()
}
[string] FunctionToMock()
{
return FunctionToMock $this
}
}
function FunctionToMock
{
param($Object)
return "This text will be replaced"
}
有了这个改变,你的测试就在我的电脑上通过了。这避免了与 PowerShell-class 相关的陷阱,但也避免了测试 class 行为。
(2) 派生和覆盖方法
您可以派生 class 并覆盖您想要模拟的方法:
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 会话中使用相同名称重新定义 classes 相关的问题(请参阅下面的旁注)。
旁注:(1) 的分离最小化了 I 运行 到 this bug that prevents classes from being reloaded when you make changes to them 的数量。不过,我发现更好的解决方法是在新的 PowerShell 会话中调用每个测试 运行(例如 PS C:\>powershell.exe -Command { Invoke-Pester }
),所以我现在倾向于 (2)。
我在尝试模拟 powershell 5 class 方法时遇到问题,在执行测试时,我收到错误“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"
}
}
我见过两种方法:
- 将大部分实现分离到一个函数中。
- 继承自 class 并覆盖该方法。
(1) 使用函数
我一直将方法的实现分离成这样的函数:
Class ChocoClass
{
[string] OutputToOverwrite()
{
return $this.FunctionToMock()
}
[string] FunctionToMock()
{
return FunctionToMock $this
}
}
function FunctionToMock
{
param($Object)
return "This text will be replaced"
}
有了这个改变,你的测试就在我的电脑上通过了。这避免了与 PowerShell-class 相关的陷阱,但也避免了测试 class 行为。
(2) 派生和覆盖方法
您可以派生 class 并覆盖您想要模拟的方法:
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 会话中使用相同名称重新定义 classes 相关的问题(请参阅下面的旁注)。
旁注:(1) 的分离最小化了 I 运行 到 this bug that prevents classes from being reloaded when you make changes to them 的数量。不过,我发现更好的解决方法是在新的 PowerShell 会话中调用每个测试 运行(例如 PS C:\>powershell.exe -Command { Invoke-Pester }
),所以我现在倾向于 (2)。