Last active
April 22, 2021 12:42
-
-
Save nohwnd/5b415fb10ff29f830ac8e98c85eee145 to your computer and use it in GitHub Desktop.
Mock interaction
This file contains hidden or 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
# ModuleName defines in which session state the mock will be effective, not in which module the function was defined. | |
# This is important when mocking functions exported from a module either when calling them from a script, or when calling | |
# them from a different module. In that case you want to define the mock in the place where the function is called from, | |
# not in the module where the function is defined. | |
# The only time you want to define the mock in the module where the function is defined is when you are testing an internal | |
# functions of the module (not shown here). | |
Invoke-Pester -Container ( | |
New-PesterContainer -ScriptBlock { | |
BeforeAll { | |
Get-Module m, n, o | Remove-Module | |
# We have 3 modules, m, n and o. We also have a function f that is defined in module m and n. | |
# The third module o internally imports the module n, and uses it's function f. | |
# This shows the interaction of the mocks when and what -ModuleName does. | |
New-Module -Name m -ScriptBlock { | |
function f () { | |
Write-Host "real f in m" | |
} | |
} | Import-Module | |
New-Module -Name n -ScriptBlock { | |
function f () { | |
Write-Host "real f in n" | |
} | |
} | Import-Module | |
New-Module -Name o -ScriptBlock { | |
function o () { | |
Write-Host "o calling f from n" | |
f | |
} | |
} | Import-Module | |
} | |
Describe "d" { | |
It "i" { | |
Write-Host "we call f from n, because both m and n export it, and n comes last so n\f shadows m\f" | |
Write-Host "when we don't use module qualified name:" | |
f | |
n\f | |
m\f | |
Write-Host "`nwe define a mock in script scope" | |
Mock f { Write-Host "Mock of f in script" } | |
Write-Host "f will resolve to the script mock:" | |
f | |
Write-Host "`we define a mock in module m" | |
Mock f -ModuleName m { Write-Host "Mock of f in m" } | |
Write-Host "f will still resolve to the script mock, or if there was none," | |
Write-Host "it would resolve to the real function exported from n:" | |
f | |
Write-Host "`nwe define a mock in module n" | |
Mock f -ModuleName n { Write-Host "Mock of f in n" } | |
Write-Host "f will still resolve to the script mock, or if there was none," | |
Write-Host "it would resolve to the real function exported from n:" | |
f | |
Write-Host "`nwe call f from inside of module m," | |
Write-Host "# it resolves to the mock defined in module m:" | |
InModuleScope m { f } | |
Write-Host "`nwe call f from inside of module n," | |
Write-Host "it resolves to the mock defined in module n:" | |
InModuleScope n { f } | |
Write-Host "`nwe call o which internally uses f. Module o is in the same situation as" | |
Write-Host "our script was originally, it cannot see any of the mocks because they are" | |
Write-Host "effective in other session states. So f resolves to the real f defined in n.:" | |
o | |
Write-Host "`nwe define mock of f in o" | |
Mock f -ModuleName o { Write-Host "Mock of f in o" } | |
Write-Host "o calls f, which resolves to the mock defined in o:" | |
o | |
} | |
} | |
}) -Output None # or use Diagnostic to see mock logging |
This file contains hidden or 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
we call f from n, because both m and n export it, and n comes last so n\f shadows m\f | |
when we don't use module qualified name: | |
real f in n | |
real f in n | |
real f in m | |
we define a mock in script scope | |
f will resolve to the script mock: | |
Mock of f in script | |
we define a mock in module m | |
f will still resolve to the script mock, or if there was none, | |
it would resolve to the real function exported from n: | |
Mock of f in script | |
we define a mock in module n | |
f will still resolve to the script mock, or if there was none, | |
it would resolve to the real function exported from n: | |
Mock of f in script | |
we call f from inside of module m, | |
# it resolves to the mock defined in module m: | |
Mock of f in m | |
we call f from inside of module n, | |
it resolves to the mock defined in module n: | |
Mock of f in n | |
we call o which internally uses f. Module o is in the same situation as | |
our script was originally, it cannot see any of the mocks because they are | |
effective in other session states. So f resolves to the real f defined in n.: | |
o calling f from n | |
real f in n | |
we define mock of f in o | |
o calls f, which resolves to the mock defined in o: | |
o calling f from n | |
Mock of f in o |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Yeah got it, I list all found behaviors, but after that filter them on ModuleName, when module name is not set (which for some reason it is not on o, and the script mock, but is set on m, and n) then they fall into the same bucket. So f from script incorrectly resolves to o. But calling f from m returns the correct behavior from mock in m.