-
-
Notifications
You must be signed in to change notification settings - Fork 476
Testing different module types
Placeholder for page explaining what different module types are there, and how to test each of them with Pester.
This page describes Pester's support for various types of PowerShell modules, and workarounds for limitations in the Mock and InModuleScope features for some module types.
PowerShell modules are a way of grouping related scripts and resources together to make it easier to use them. There are a number of different types of modules, each of which have slightly different characteristics:
- Script modules
- Binary modules
- Manifest modules
- Dynamic modules
You can determine what type a specific modules is by using Import-Module
to import it, and then using Get-Module
to show its details. The ModuleType
property will be one of the above values.
Note that these types are described more fully in the Understanding a Windows PowerShell Module page on the Microsoft TechNet website.
Pester can be used to test the behavior of commands that are exported from all types of modules. For example the following test will call the Invoke-PublicMethod
command regardless of whether it is defined in a Script, Binary, Manifest or Dynamic module:
Describe "Invoke-PublicMethod" {
It "returns a value" {
$result = Invoke-PublicMethod
$result | Should Be "Invoke-PublicMethod called!"
}
}
However, the Mock and InModuleScope features can only be used for commands in Script modules due to limitations in the way that other module types are implemented in PowerShell. As a result, you may see error message when trying to use Mock or InModuleScope with non-Script modules:
Module 'MyManifestModule' is not a Script module. Detected modules of the following types: 'Manifest'
The following sections describe Pester's support for the Mock and InModuleScope features for each type of module, and workarounds for the error above, if available.
Pester fully supports Script modules, so the Mock and InModuleScope features can be used without any workarounds.
The Mock and InModuleScope features can be used with Dynamic modules if the module is first imported using Import-Module
. For example:
# create a dynamic module
$myDynamicModule = New-Module -Name MyDynamicModule {
function InternalFunction { 'I am the internal function' }
function PublicFunction { InternalFunction }
Export-ModuleMember -Function PublicFunction
}
# import the dynamic module
$myDynamicModule | Import-Module -Force
# use InModuleScope and Mock for commands inside the dynamic module
Describe "Executing test code inside a dynamic module" {
It "Can mock functions inside the module when using Mock -ModuleName" {
Mock InternalFunction MyDynamicModule { 'I am the mock function.' }
PublicFunction | Should -Be 'I am the mock function.'
AssertMock InternalFunction MyDynamicModule
}
InModuleScope MyDynamicModule {
It "Can call module internal functions using InModuleScope" {
InternalFunction | Should -Be 'I am the internal function'
}
It "Can mock functions inside the module without using Mock -ModuleName" {
Mock InternalFunction { 'I am the mock function.' }
InternalFunction | Should -Be 'I am the mock function.'
}
}
}
Commands that are exported from a manifest module can be tested with Pester, but the Mock and InModuleScope features cannot be used with Manifest modules.
There is, however, a simple workaround, which is to add an empty script module with a *.psm1 extension into the RootModule (or ModulesToProcess) attribute of the manifest *.psd1 file. This basically converts the Manifest module into a Script module instead.
For example, save the script below as "MyModule.psd1" to create a PowerShell Manifest module.
@{
ModuleVersion = '1.0'
NestedModules = @( "Invoke-PrivateManifestMethod.ps1", "Invoke-PublicManifestMethod.ps1" )
FunctionsToExport = @( "Invoke-PublicManifestMethod" )
}
Then, to convert it into a Script module, create a new blank file called "MyModule.psm1" and modify the MyModule.pasd1 as follows:
@{
ModuleVersion = '1.0'
RootModule = "MyModule.psm1" # <-- add this line to convert a Manifest module into a Script module
NestedModules = @( "Invoke-PrivateManifestMethod.ps1", "Invoke-PublicManifestMethod.ps1" )
FunctionsToExport = @( "Invoke-PublicManifestMethod" )
}
PowerShell will then load the module as a Script module instead, and Pester's Mock and InModuleScope features will work as per normal.
Commands that are exported from a Binary module can be tested with Pester, but the Mock and InModuleScope features cannot be used with Binary modules, and there are unfortunately no workarounds at present.