How to define an 'It' test for a nested function in Pester 5?

377 Views Asked by At

Given a PowerShell script (.ps1) with functions and nested functions. The function 'Inner' should not be moved to the outer scope and thus not be exported. How can one define an 'It' test for the 'Inner' function (hopefully without modifying the code)?

Using: PS core 7.1.4:

Function Outer {
    Function Inner {
        # ...
    }
    # ...
}

Using: Pester 5.3.0:

Describe "A" {
    It "A" { Outer } | Should -be $null  # OK
    It "B" { Inner } | Should -be $null  # ERROR
}
1

There are 1 best solutions below

0
On

If you really must do this, there is a way but it involves searching through the abstract syntax tree. This might be a bit complex, but it does the job.

So you have the functions defined as such:

Function Outer {
    Function Inner {
        # ...
    }
    # ...
}

You can find the scriptblock of the Inner function as follows:

$outerCommandInfo = Get-Command -Name 'Outer'
$innerDefinition = $outerCommandInfo.ScriptBlock.Ast.FindAll( { param($ast) $ast -is [System.Management.Automation.Language.FunctionDefinitionAst] }, $true) | ? Name -eq 'Inner'
$innerScriptBlock = $innerDefinition.Body.GetScriptBlock()

Now, in the $innerScriptBlock variable you have the definition of the Inner function. You can invoke it using the call operator or simply $innerScriptBlock.Invoke()

It will be a little trickier to pass parameters and to test it.

Describe "A" {
    BeforeAll {
        # the code above
    }

    It "A" { Outer } | Should -be $null  # OK
    It "B" { & $innerScriptBlock } | Should -be $null  # OK?
}