我正在研究一些Pester测试用例,并且我正在查看CodeCoverage结果。在大多数测试用例集中,我们的代码包含try / catch,我们在catch上获得0%的覆盖率。这是一个例子:
function Test-Is64Bit()
{
$Result = $false
try
{
if ((Get-WmiObject -Class "Win32_OperatingSystem").OSArchitecture -eq '64-bit')
{
$Result = $true
}
}
catch
{
Write-Error $_.Exception | Format-List -Force
}
return $Result
}
很容易模拟Get-WmiObject返回值来测试$ true条件。
我已经尝试过一些想法来模拟Get-WmiObject中的异常但是在每种情况下异常都会传递到控制台而不是被Pester捕获并通过测试。以下是我提出的最好的,但它仍然无法正常工作。
Context "Unit tests for Get-WmiObject exception" {
# mock the Get-WmiObject cmdlet for unit testing
Mock Get-WmiObject {
Throw
} -ParameterFilter { $Class -And $Class -eq 'Win32_OperatingSystem' }
It "Function test passes" {
{ Test-Is64Bit } | Should Be $false
Assert-MockCalled Get-WmiObject -Scope It -Exactly -Times 1
}
}
此测试结果为:
Context Unit tests for Get-WmiObject error
[-] Function test passes 138ms
Expected: {False}
But was: { Test-Is64Bit }
at line: 62 in .\Tests\Test-Is64Bit.Tests.ps1
62: { Test-Is64Bit } | Should Be $false
Tests completed in 590ms
Tests Passed: 4 Failed: 1 Skipped: 0 Pending: 0 Inconclusive: 0
Code coverage report:
Covered 80.00 % of 10 analyzed Commands in 1 File.
Missed commands:
File Function Line Command
---- -------- ---- -------
Test-Is64Bit.ps1 Test-Is64Bit 38 Write-Error $_.Exception
Test-Is64Bit.ps1 Test-Is64Bit 38 Format-List -Force
是否有任何方法可以模拟Get-WmiObject抛出的异常,这样我们就可以让Pester陷入捕获并最终实现100%的代码覆盖率?
我当前的测试代码正在寻找异常
Context "Unit tests for Get-WmiObject exception" {
# mock the Get-WmiObject cmdlet for unit testing
Mock Get-WmiObject {
Throw 'Some Error'
} -ParameterFilter { $Class -And $Class -eq 'Win32_OperatingSystem' }
It 'Get-WmiObject should throw' {
{ Get-WmiObject -Class 'Win32_OperatingSystem' } | Should Throw 'Some Error'
}
It "Throws exception" {
{ Test-Is64Bit } | Should Throw 'Some Error'
Assert-MockCalled Get-WmiObject -Scope It -Exactly -Times 1
}
}
以上代码导致:
Context Unit tests for Get-WmiObject exception
[+] Get-WmiObject should throw 89ms
Test-Is64Bit : System.Management.Automation.RuntimeException: Some Error At
C:\ONESolutionFinance\Main\ReleaseManagement\PowerShell-Module\SPSNoDeps\Tests\Test-Is64Bit.Tests.ps1:66
char:7
+ { Test-Is64Bit } | Should Throw 'Some Error'
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Test-Is64Bit
[-] Throws exception 51ms
Expected: the expression to throw an exception with message {Some Error}, an exception was not raised, message was {}
from line:2 char:5
+ Throw 'Some Error'
+ ~~~~~~~~~~~~~~~~~~
at line: 66 in C:\ONESolutionFinance\Main\ReleaseManagement\PowerShell-Module\SPSNoDeps\Tests\Test-Is64Bit.Tests.ps1
66: { Test-Is64Bit } | Should Throw 'Some Error'
测试$ false会返回:
Context Unit tests for Get-WmiObject exception
[+] Get-WmiObject should throw 162ms
Test-Is64Bit : System.Management.Automation.RuntimeException: Some Error
At C:\ONESolutionFinance\Main\ReleaseManagement\PowerShell-Module\SPSNoDeps\Tests\Test-Is64Bit.Tests.ps1:66 char:5
+ Test-Is64Bit | Should Be $false
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
+ FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException,Test-Is64Bit
[+] Throws exception 92ms
答案 0 :(得分:5)
是的,它可以!这是一个例子:
Describe 'Mock an exception' {
Mock Get-WMIObject { Throw 'some error' }
It 'Get-WMIObject should throw' {
{Get-WMIObject -class someclass} | Should Throw 'some error'
}
}
我认为您的代码不起作用,因为:
{ Test-Is64Bit } | Should Be $false
应该是:
{ Test-Is64Bit } | Should Throw
您在{ }
使用Should
之前使用ScriptBlock Should Throw
。
答案 1 :(得分:0)
function Test-LocalFile
{
param (
[string]
$filepath
)
try {
$FileInfo = get-item -Path $filepath -ErrorAction SilentlyContinue
if ($FileInfo.getType().Name -eq "FileInfo") {
return $true
}
} catch {
Write-Error -Message "$($_.Exception.Message)"
Throw
}
}
这是上层定义函数如何处理异常的总解决方案
Describe "Unit testing for exception handling" {
Context "unit test showing exception"{
#arrange
Mock Write-Error{}
Mock get-item {
Throw 'some error'
}
#act
Write-Error 'some error'
#assert
It "test-Local FileThrows exception" {
{Test-LocalFile -filepath test.txt} | Should Throw 'some error'
Assert-MockCalled get-item -Scope It -Exactly -Times 1
}
}
}