Powershell 佩斯特怎么能嘲弄这句话;测试“;“模式中的功能”;测试存在性(未找到)-创建-再次测试以确认创建“;?
下面是一些显示要测试的函数的伪代码:Powershell 佩斯特怎么能嘲弄这句话;测试“;“模式中的功能”;测试存在性(未找到)-创建-再次测试以确认创建“;?,powershell,unit-testing,pester,Powershell,Unit Testing,Pester,下面是一些显示要测试的函数的伪代码: function Set-Something { if (Test-Something) { return $True } # Not found so do something to create it. Do-Something # Check it's been created successfully. if (Test-Something) { re
function Set-Something
{
if (Test-Something)
{
return $True
}
# Not found so do something to create it.
Do-Something
# Check it's been created successfully.
if (Test-Something)
{
return $True
}
return $False
}
这必须是一个相当常见的模式:“测试是否存在-如果找不到创建-再次测试以验证创建”。测试大多数分支非常简单,但是如果在第一次调用某个分支时测试失败,然后在第二次调用时测试成功,那么如何测试该分支呢
这是我目前为止的测试代码:
Describe 'Set-Something' {
Context 'already exists' {
Mock Test-Something { return $True }
Mock Do-Something
It 'returns True' {
{ Set-Something } | Should -Be $True
}
It 'does not call Do-Something' {
Set-Something
Assert-MockCalled Do-Something -Times 0 -Exactly
}
}
Context 'does not already exist and creation fails' {
Mock Test-Something { return $False }
Mock Do-Something
It 'calls Do-Something' {
Set-Something
Assert-MockCalled Do-Something -Times 1 -Exactly
}
It 'calls Test-Something twice' {
Set-Something
Assert-MockCalled Test-Something -Times 2 -Exactly
}
It 'returns False' {
{ Set-Something } | Should -Be $False
}
}
Context 'does not already exist and creation succeeds' {
Mock Test-Something { ?? }
Mock Do-Something
It 'calls Do-Something' {
Set-Something
Assert-MockCalled Do-Something -Times 1 -Exactly
}
It 'calls Test-Something twice' {
Set-Something
Assert-MockCalled Test-Something -Times 2 -Exactly
}
It 'returns True' {
{ Set-Something } | Should -Be $True
}
}
}
问题在于案例“不存在且创建成功”。测试某些东西需要被模拟,这样它第一次调用失败,第二次调用成功。每个调用中传递给测试对象的参数都是相同的,因此我不能使用ParameterFilter创建两个行为不同的测试对象模拟。我找到了两种模拟方法: 1)使用“静态”(即脚本范围)变量记录状态
Context 'does not already exist and creation succeeds' {
BeforeEach {
$script:exists = $False
}
AfterAll {
Remove-Variable exists -Scope Script
}
Mock Test-Something {
return $script:exists
}
Mock Do-Something {
$script:exists = $True
}
It 'calls Do-Something' {
Set-Something
Assert-MockCalled Do-Something -Times 1 -Exactly
}
It 'calls Test-Something twice' {
Set-Something
Assert-MockCalled Test-Something -Times 2 -Exactly
}
It 'returns True' {
{ Set-Something } | Should -Be $True
}
}
Context 'does not already exist and creation succeeds' {
BeforeEach {
$mockState = @{
ItExists = $False
}
}
Mock Test-Something {
return $mockState.ItExists
}
Mock Do-Something {
$mockState.ItExists = $True
}
It 'calls Do-Something' {
Set-Something
Assert-MockCalled Do-Something -Times 1 -Exactly
}
It 'calls Test-Something twice' {
Set-Something
Assert-MockCalled Test-Something -Times 2 -Exactly
}
It 'returns True' {
{ Set-Something } | Should -Be $True
}
}
2)使用哈希表记录状态
Context 'does not already exist and creation succeeds' {
BeforeEach {
$script:exists = $False
}
AfterAll {
Remove-Variable exists -Scope Script
}
Mock Test-Something {
return $script:exists
}
Mock Do-Something {
$script:exists = $True
}
It 'calls Do-Something' {
Set-Something
Assert-MockCalled Do-Something -Times 1 -Exactly
}
It 'calls Test-Something twice' {
Set-Something
Assert-MockCalled Test-Something -Times 2 -Exactly
}
It 'returns True' {
{ Set-Something } | Should -Be $True
}
}
Context 'does not already exist and creation succeeds' {
BeforeEach {
$mockState = @{
ItExists = $False
}
}
Mock Test-Something {
return $mockState.ItExists
}
Mock Do-Something {
$mockState.ItExists = $True
}
It 'calls Do-Something' {
Set-Something
Assert-MockCalled Do-Something -Times 1 -Exactly
}
It 'calls Test-Something twice' {
Set-Something
Assert-MockCalled Test-Something -Times 2 -Exactly
}
It 'returns True' {
{ Set-Something } | Should -Be $True
}
}
就个人而言,我喜欢哈希表,因为$mockState在我看来,code>比$script:…
更能说明变量的用途。此外,如果测试曾经被并行化,并且另一个descripe块修改了相同的变量,那么脚本范围的变量可能会导致竞争条件