Professional Documents
Culture Documents
About Mocking - Help
About Mocking - Help
Mocking
SYNOPSIS
Pester provides a set of Mocking functions making it easy to fake
dependencies
and also to verify behavior. Using these mocking functions can allow you to
"shim" a data layer or mock other complex functions that already have their
own tests.
DESCRIPTION
With the set of Mocking functions that Pester exposes, one can:
MOCKING FUNCTIONS
See Get-Help for any of the below functions for more detailed information.
Mock
Mocks the behavior of an existing command with an alternate
implementation.
Assert-VerifiableMocks
Checks if any Verifiable Mock has not been invoked. If so, this will
throw an exception.
Assert-MockCalled
Checks if a Mocked command has been called a certain number of times
and throws an exception if it has not.
EXAMPLE
function Build ($version) {
Write-Host "a build was run for version: $version"
}
function BuildIfChanged {
$thisVersion = Get-Version
$nextVersion = Get-NextVersion
if ($thisVersion -ne $nextVersion) { Build $nextVersion }
return $nextVersion
}
Describe "BuildIfChanged" {
Context "When there are Changes" {
Mock Get-Version {return 1.1}
Mock Get-NextVersion {return 1.2}
Mock Build {} -Verifiable -ParameterFilter {$version -eq 1.2}
$result = BuildIfChanged
$result = BuildIfChanged
Let's say you have code like this inside a script module (.psm1 file):
function BuildIfChanged {
$thisVersion = Get-Version
$nextVersion = Get-NextVersion
if ($thisVersion -ne $nextVersion) { Build $nextVersion }
return $nextVersion
}
You wish to write a unit test for this module which mocks the calls to Get-Version
and Get-NextVersion from the module's BuildIfChanged command. In older versions of
Pester, this was not possible. As of version 3.0, there are two ways you can
perform
unit tests of PowerShell script modules. The first is to inject mocks into a
module:
For these example, we'll assume that the PSM1 file is named "MyModule.psm1", and
that
it is installed on your PSModulePath.
Import-Module MyModule
Describe "BuildIfChanged" {
Context "When there are Changes" {
Mock -ModuleName MyModule Get-Version { return 1.1 }
Mock -ModuleName MyModule Get-NextVersion { return 1.2 }
# Just for giggles, we'll also mock Write-Host here, to demonstrate that you
can
# mock calls to commands other than functions defined within the same module.
Mock -ModuleName MyModule Write-Host {} -Verifiable -ParameterFilter {
$Object -eq 'a build was run for version: 1.2'
}
$result = BuildIfChanged
$result = BuildIfChanged
Notice that in this example test script, all calls to Mock and Assert-MockCalled
have had the
-ModuleName MyModule parameter added. This tells Pester to inject the mock into the
module's scope,
which causes any calls to those commands from inside the module to execute the mock
instead.
When you write your test script this way, you can mock commands that are called by
the module's
internal functions. However, your test script is still limited to accessing the
public, exported
members of the module. If you wanted to write a unit test that calls Build
directly, for example,
it wouldn't work using the above technique. That's where the second approach to
script module testing
comes into play. With Pester 3.0's InModuleScope command, you can cause entire
sections of your test
script to execute inside the targeted script module. This gives you access to non-
exported members of
the module. For example:
Import-Module MyModule
Build $testVersion
Notice that when using InModuleScope, you no longer need to specify a -ModuleName
parameter when calling
Mock or Assert-MockCalled for commands within that module. You are also able to
directly call the Build
function, which the module does not export.
SEE ALSO
Mock
Assert-VerifiableMocks
Assert-MockCalled
InModuleScope
Describe
Context
It