Last active
August 3, 2017 16:36
-
-
Save alx9r/56bbc9077b39e5693b08821183d89c21 to your computer and use it in GitHub Desktop.
Tests summarizing scope-related differences for mocks between Pester 3 and 4
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$guid = [guid]::NewGuid().Guid | |
$guidFrag = $guid.Split('-')[0] | |
$h = @{} | |
$h.MyInvocation = $MyInvocation | |
$directlyInvoked = -not [bool]$h.MyInvocation.Line | |
$h.TempTestScript = "$([System.IO.Path]::GetTempPath())\$guidFrag.Tests.ps1" | |
function Set-PesterVersion | |
{ | |
[CmdletBinding()] | |
param | |
( | |
[ValidateSet('3','4')] | |
[string]$Version | |
) | |
process | |
{ | |
$versionTest = @{ | |
'3' = { $_.Version -lt '4.0.0' } | |
'4' = { $_.Version -ge '4.0.0' } | |
}.$Version | |
Remove-Module Pester -ErrorAction SilentlyContinue | |
$module = Get-Module -ListAvailable Pester | | |
? $versionTest | | |
Select -First 1 | |
if ( -not $module ) | |
{ | |
throw "Pester module version $Version not found." | |
} | |
$module | Import-Module -ErrorAction SilentlyContinue | |
$module = Get-Module Pester | | |
? $versionTest | |
if ( -not $module ) | |
{ | |
throw "Failed to load Pester module version $Version." | |
} | |
Write-Output "Pester $Version" | |
} | |
} | |
$setup = { | |
function Set-TestModules | |
{ | |
# import one dynamic module from another' | |
# create module A' | |
$h.ModuleA = New-Module -Name "ModuleA-$guid" -ScriptBlock ( | |
[scriptblock]::Create(@" | |
function A1-$guid { 'real result of A1' } | |
function A2-$guid { "A2 calls A1: `$(A1-$guid)" } | |
"@ | |
)) | |
$h.ModuleA | Import-Module -Force -WarningAction SilentlyContinue | |
# create module B' | |
$h.ModuleB = New-Module -Name "ModuleB-$guid" -ScriptBlock ( | |
[scriptblock]::Create(@" | |
Get-Module ModuleA-$guid | Import-Module -WarningAction SilentlyContinue | |
function B-$guid { "B calls A1: `$(A1-$guid)" } | |
"@ | |
)) | |
$h.ModuleB | Import-Module -Force -WarningAction SilentlyContinue | |
#create module C | |
$h.ModuleC = New-Module -Name "ModuleC-$guid" -ScriptBlock ( | |
[scriptblock]::Create("function C-$guid { `"C calls A1: `$(A1-$guid)`" }" ) | |
) | |
$h.ModuleC | Import-Module -Force -WarningAction SilentlyContinue | |
} | |
} | |
function Invoke-TestWithPester | |
{ | |
param | |
( | |
[scriptblock] | |
$ScriptBlock | |
) | |
{ $directlyInvoked = $false }.ToString() + | |
$ScriptBlock.ToString() + | |
$setup.ToString() | | |
Set-Content $h.TempTestScript | |
Invoke-Pester $h.TempTestScript | |
} | |
& $setup | |
Set-TestModules | |
Describe 'test the test modules' { | |
It 'command in inner module works' { | |
$r = & "A1-$guid" | |
$r | Should be 'real result of A1' | |
} | |
It 'command in outer module calls inner module' { | |
$r = & "B-$guid" | |
$r | Should be 'B Calls A1: real result of A1' | |
} | |
It 'command in outer module calls inner module even though inner module is not imported' { | |
$r = & "C-$guid" | |
$r | Should be 'C Calls A1: real result of A1' | |
} | |
} | |
foreach ( $values in @( | |
@('directly (like F5 does)',{ & $test }), | |
@('with Invoke-Pester',{ Invoke-TestWithPester $test }) | |
)) | |
{ | |
$methodName,$invoker = $values | |
Write-Output "#### Invoking Test $methodName ####" | |
Set-PesterVersion 3 | |
$test = { | |
Describe "Pester 3: effect of InModuleScope on whether a mock or real command is invoked" { | |
Context 'indirectly invoke mocked command from another module without InModuleScope' { | |
Mock "A1-$guid" { 'mocked result of A1' } | |
It 'returns result from real function' { | |
$r = & "B-$guid" | |
$r | Should be 'B calls A1: real result of A1' | |
} | |
} | |
Context 'indirectly invoke mocked command from mocked command''s module without InModuleScope' { | |
Mock "A1-$guid" { 'mocked result of A1' } | |
It 'returns result from real function' { | |
$r = & "A2-$guid" | |
$r | Should be 'A2 calls A1: real result of A1' | |
} | |
} | |
} | |
} | |
& $invoker | |
Set-PesterVersion 4 | |
$test = { | |
Describe 'Pester 4: effect of InModuleScope on whether a mock or real command is invoked' { | |
Context 'indirectly invoke mocked command from another module without InModuleScope' { | |
Mock "A1-$guid" { 'mocked result of A1' } | |
if ( $directlyInvoked ) | |
{ | |
It 'returns result from mock (when script invoked directly)' { | |
$r = & "B-$guid" | |
$r | Should be 'B calls A1: mocked result of A1' | |
} | |
} | |
else | |
{ | |
It 'returns result from real function (when script invoked by Pester)' { | |
$r = & "B-$guid" | |
$r | Should be 'B calls A1: real result of A1' | |
} | |
} | |
} | |
Context 'indirectly invoke mocked command from mocked command''s module without InModuleScope' { | |
Mock "A1-$guid" { 'mocked result of A1' } | |
if ( $directlyInvoked ) | |
{ | |
It 'returns result from mock (when scripted invoked directly)' { | |
$r = & "A2-$guid" | |
$r | Should be 'A2 calls A1: mocked result of A1' | |
} | |
} | |
else | |
{ | |
It 'returns result from real function (when scripted invoked by Pester)' { | |
$r = & "A2-$guid" | |
$r | Should be 'A2 calls A1: real result of A1' | |
} | |
} | |
} | |
} | |
} | |
& $invoker | |
Set-PesterVersion 3 | |
$test = { | |
Describe 'Pester 3: effect of not importing module inside module that invokes mocked command' { | |
It 'set TestDrive file contents' { | |
$guid | Set-Content 'TestDrive:\guid.txt' | |
} | |
if ( $directlyInvoked ) | |
{ | |
Context 'indirectly invoke mocked command from another non-importing module without InModuleScope' { | |
Mock "A1-$guid" { 'mocked result of A1' } | |
It 'returns result from real function (when script invoked directly)' { | |
$r = & "C-$guid" | |
$r | Should be 'C calls A1: mocked result of A1' | |
} | |
} | |
} | |
else | |
{ | |
Context 'indirectly invoke mocked command from another non-importing module without InModuleScope' { | |
Mock "A1-$guid" { 'mocked result of A1' } | |
It 'throws CommandNotFoundException for mocked command (when script invoked by Pester)' { | |
try | |
{ | |
& "C-$guid" | |
} | |
catch | |
{ | |
$threw = $true | |
$_.FullyQualifiedErrorId | Should be CommandNotFoundException | |
$_ | Should match "The term 'A1" | |
} | |
$threw | Should be $true | |
} | |
} | |
InModuleScope "ModuleA-$guid" { | |
$guid = Get-Content 'TestDrive:\guid.txt' | |
Context 'indirectly invoke mocked command from another non-importing module InModuleScope of the mocked command''s module' { | |
Mock "A1-$guid" { 'mocked result of A1' } | |
It 'throws CommandNotFoundException for mocked command (when script invoked by Pester)' { | |
try | |
{ | |
& "C-$guid" | |
} | |
catch | |
{ | |
$threw = $true | |
$_.FullyQualifiedErrorId | Should be CommandNotFoundException | |
$_ | Should match "The term 'A1" | |
} | |
$threw | Should be $true | |
} | |
} | |
} | |
InModuleScope "ModuleC-$guid" { | |
$guid = Get-Content 'TestDrive:\guid.txt' | |
Context 'indirectly invoke mocked command from another non-importing module InModuleScope of non-importing module' { | |
try | |
{ | |
Mock "A1-$guid" { 'mocked result of A1' } | |
} | |
catch [System.Management.Automation.CommandNotFoundException] | |
{ | |
$threw = $true | |
$exception = $_ | |
} | |
It 'throws CommandNotFoundException when mocking command (when script invoked by Pester)' { | |
$threw | Should be $true | |
} | |
} | |
} | |
} | |
} | |
} | |
& $invoker | |
Set-PesterVersion 4 | |
$test = { | |
Describe 'Pester 4: effect of not importing module inside module that invokes mocked command' { | |
It 'set TestDrive file contents' { | |
$guid | Set-Content 'TestDrive:\guid.txt' | |
} | |
Context 'indirectly invoke mocked command from another non-importing module without InModuleScope' { | |
Mock "A1-$guid" { 'mocked result of A1' } | |
if ( $directlyInvoked ) | |
{ | |
It 'returns result from mock (when script invoked directly)' { | |
$r = & "C-$guid" | |
$r | Should be 'C calls A1: mocked result of A1' | |
} | |
} | |
else | |
{ | |
It 'returns result from real function (when script invoked by Pester)' { | |
$r = & "C-$guid" | |
$r | Should be 'C calls A1: real result of A1' | |
} | |
} | |
} | |
if ( -not $directlyInvoked ) | |
{ | |
InModuleScope "ModuleA-$guid" { | |
$guid = Get-Content 'TestDrive:\guid.txt' | |
Context 'indirectly invoke mocked command from another non-importing module InModuleScope of the mocked command''s module' { | |
Mock "A1-$guid" { 'mocked result of A1' } | |
It 'returns result from real function (when script invoked directly)' { | |
$r = & "C-$guid" | |
$r | Should be 'C calls A1: real result of A1' | |
} | |
} | |
} | |
} | |
} | |
} | |
& $invoker | |
} | |
Remove-Variable 'guid','h' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment