Reputation: 193
I am testing a PowerShell script. I'd like to test individual functions without executing the entire script. I am not sure if this is the intended use case or supported, and I am not finding a good answer searching online
Param(
[Parameter(Mandatory = $true,
Position = 0)]
[ValidateNotNullOrEmpty()]
[string] $Message
)
function fut([string] $argument) {
Write-Host $argument
}
function Main() {
fut($Message)
}
Main
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path) -replace '\.Tests\.', '.'
. "$here\$sut" "Message"
Describe "fut" {
It "does something useful" {
fut 'beer'
}
}
Message
Describing fut
beer
[+] does something useful 385ms
Tests completed in 385ms
Now I can mock away 'beer', because it runs in the describe block. But I cannot mock away 'message', because the script starts to execute when I dot-source it.
In my case, 'message' is an operation I do not want to execute.
I am on Windows 10 15063.
Upvotes: 6
Views: 1447
Reputation: 126
If you, for some reason
one approach is to add logic that skips auto-executing the script's functionality when a switch parameter is supplied.
I use something like that to keep my Azure Automation runbooks simple (simplicity is debatable; here "simple" translates to "keeping all functionality in a single script file") and testable:
SingleScript.Tests.ps1
BeforeAll {
. $PSScriptRoot/SingleScript.ps1 -InTestContext
}
Describe 'SingleScript' {
Context 'Invoke-Functionality' {
It 'invokes script functionality' {
$result = Invoke-Functionality
$result | Should -Be 'Something useful'
}
}
}
In the test file above, within the BeforeAll
block, auto-execution when dot sourcing is skipped with the switch parameter InTestContext
.
SingleScript.ps1
param(
[switch]
$InTestContext
)
function Invoke-Functionality {
'Something useful'
}
if (-not $InTestContext) {
Invoke-Functionality
}
In the script file above, you can see the logic that allows skipping auto-execution.
Upvotes: 2
Reputation: 1
This will only run the main function if it is not called ny Dot Source, as a pester script would. I am using this instead of splitting functions to another file where it is not needed. Then pester runs without invoking the Main function.
if (-not ($MyInvocation.InvocationName -eq "."))
{
Main
}
Upvotes: 0
Reputation: 23395
Per the comments, the issue is that your script is self-executing, so it's not possible to load it for Pester via dot-sourcing without also executing the functions.
The workaround suggested by Roman to temporarily use Set-Alias
to set main
to Out-Null
would work. Another suggestion would be to separate your functions to a separate file (e.g named functions.ps1
) and then in your original script you can use dot sourcing to include it, but in your test script just dot source the functions.ps1
file.
Upvotes: 5