jamacoe
jamacoe

Reputation: 549

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

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
}

Upvotes: 0

Views: 466

Answers (1)

Vivere
Vivere

Reputation: 2280

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?
}

Upvotes: 0

Related Questions