Skip to content

Commit e1f2361

Browse files
authored
Do not cleanup previous mocks in inner Invoke-Pester (#2337)
1 parent c5dd825 commit e1f2361

File tree

3 files changed

+45
-10
lines changed

3 files changed

+45
-10
lines changed

src/Main.ps1

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -670,16 +670,17 @@ function Invoke-Pester {
670670
# this will inherit to child scopes and allow Describe / Context to run directly from a file or command line
671671
$invokedViaInvokePester = $true
672672

673+
if ($null -eq $state) {
674+
# Cleanup any leftover mocks from previous runs, but only if we are not running in a nested Pester-run
675+
# todo: move mock cleanup to BeforeAllBlockContainer when there is any?
676+
Remove-MockFunctionsAndAliases -SessionState $PSCmdlet.SessionState
677+
}
678+
673679
# this will inherit to child scopes and allow Pester to run in Pester, not checking if this is
674680
# already defined because we want a clean state for this Invoke-Pester even if it runs inside another
675681
# testrun (which calls Invoke-Pester itself)
676682
$state = New-PesterState
677683

678-
# TODO: Remove all references to mock table, there should not be many.
679-
$script:mockTable = @{}
680-
# todo: move mock cleanup to BeforeAllBlockContainer when there is any
681-
Remove-MockFunctionsAndAliases -SessionState $PSCmdlet.SessionState
682-
683684
# store CWD so we can revert any changes at the end
684685
$initialPWD = $pwd.Path
685686
}

src/functions/Pester.SessionState.Mock.ps1

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,7 +1201,9 @@ function Invoke-Mock {
12011201
# if we are targeting a module use the behaviors for the current module, but if there is no default the fall back to the non-module default behavior.
12021202
# do not fallback to non-module filtered behaviors. This is here for safety, and for compatibility when doing Mock Remove-Item {}, and then mocking in module
12031203
# then the default mock for Remove-Item should be effective.
1204-
$behaviors = if ($targettingAModule) {
1204+
1205+
# using @() to always get array. This avoids null error in Invoke-MockInternal when no behaviors where found (if-else unwraps the lists)
1206+
$behaviors = @(if ($targettingAModule) {
12051207
# we have default module behavior add it to the filtered behaviors if there are any
12061208
if ($null -ne $moduleDefaultBehavior) {
12071209
$moduleBehaviors.Add($moduleDefaultBehavior)
@@ -1223,7 +1225,7 @@ function Invoke-Mock {
12231225
}
12241226

12251227
$nonModuleBehaviors
1226-
}
1228+
})
12271229

12281230
$callHistory = (Get-MockDataForCurrentScope).CallHistory
12291231

tst/functions/Mock.Tests.ps1

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1287,9 +1287,6 @@ Describe 'Dot Source Test' {
12871287
}
12881288

12891289
It "Doesn't call the mock with any other parameters" {
1290-
InPesterModuleScope {
1291-
$global:calls = $mockTable['||Test-Path'].CallHistory
1292-
}
12931290
Should -Invoke Test-Path -Exactly 0 -ParameterFilter { $Path -ne 'Test' } -Scope Describe
12941291
}
12951292
}
@@ -3138,3 +3135,38 @@ Describe 'Mocking in manifest modules' {
31383135
Should -Invoke -CommandName 'myManifestPrivateFunction' -ModuleName $moduleName -Exactly -Times 1
31393136
}
31403137
}
3138+
3139+
Describe 'Mocking with nested Pester runs' {
3140+
BeforeAll {
3141+
Mock Get-Date { 1 }
3142+
3143+
$innerRun = Invoke-Pester -Container (New-PesterContainer -ScriptBlock {
3144+
Describe 'inner' {
3145+
It 'local mock works' {
3146+
Mock Get-Command { 2 }
3147+
Get-Command | Should -Be 2
3148+
}
3149+
3150+
It 'outer mock is not available' {
3151+
Get-Date | Should -Not -Be 1
3152+
}
3153+
}
3154+
}) -Output None -PassThru
3155+
}
3156+
3157+
It 'Mocks in outer run works after nested Invoke-Pester' {
3158+
# https://github.com/pester/Pester/issues/2074
3159+
Get-Date | Should -Be 1
3160+
# Outer mock should not have been called from nested run
3161+
Should -Invoke Get-Date -Exactly -Times 1
3162+
}
3163+
3164+
It 'Mocking works in nested run' {
3165+
$innerRun.Result | Should -Be 'Passed'
3166+
$innerRun.PassedCount | Should -Be 2
3167+
}
3168+
3169+
It 'Mocks in nested run do not leak to outside' {
3170+
Get-Command Get-ChildItem | Should -Not -Be 2
3171+
}
3172+
}

0 commit comments

Comments
 (0)