1

I have the following declarations:

function Get-Datastore { [CmdletBinding()] param ($Name, $Id, $Server, [Parameter(ValueFromPipeline = $true)]$Location) }
function Get-ScsiLun { [CmdletBinding()] param ($Server, [Parameter(ValueFromPipeline = $true)]$Datastore) }

With these simple Mocks:

Mock Get-Datastore {
    return $mockDatastores
}
Mock Get-ScsiLun {
    return $mockLuns
}

The partial code (from Get-XxxScsiLun function):

$datastores = $VMHost |
    Get-Datastore -Server $Server -PipelineVariable "datastore" |
    Where-Object { $datastore.Type -eq "VMFS" } |
    Get-ScsiLun -Server $Server |
    Select-Object -Property "CanonicalName", @{ "Name" = "Datastore"; "Expression" = { $datastore.Name } }

The Pester test (simplified):

It "Should return the luns" {
    $result = Get-XxxScsiLun -VMHost $mockVmHost
    $result | Should -HaveCount 2
}

The Pester test fails with:

[-] Should return the luns 21ms
    RuntimeException: The variable '$datastore' cannot be retrieved because it has not been set.

So my question is: How can I support -PipelineVariabele from Pester?

Note1: I don't want to change the original code, so using $_ instead of the pipeline variable is not desired

Note2: Adding Set-Variable -Name "datastore" -Scope 3 -Value $mockDatastores to the Get-Datastore mock defines the $datastore in the correct scope, but containing all datastores instead of 1 (per pipeline call)

Update: Working example to show the error:

$ErrorActionPreference = "Stop"
Set-StrictMode -Version Latest

function Get-XxxScsiLun
{
    $datastores = Get-Datastore -PipelineVariable "datastore" |
        Where-Object { $datastore.Type -eq "VMFS" }
    return $datastores
}

Describe "Happy flow" {
    BeforeAll {
        function Get-Datastore { [CmdletBinding()] param () }

        $mockDatastores = @(
            [PSCustomObject]@{ "Name" =  "ds1"; "Type" = "VMFS" },
            [PSCustomObject]@{ "Name" =  "ds2"; "Type" = "NFS" }
        )

        Mock Get-Datastore {
            return $mockDatastores
        }
    }

    It "Should return the luns" {
        $result = Get-XxxScsiLun
        $result | Should -HaveCount 1
    }
}
mhu
  • 17,720
  • 10
  • 62
  • 93
  • A reproducible example could be helpful. For me it's kinda hard to imagine how the snippets presented here play together to produce the problem. – zett42 Jan 08 '21 at 19:06
  • Sure, added example – mhu Jan 09 '21 at 18:10
  • In general Mocks are not pipeline-aware yet, see https://github.com/pester/Pester/issues/2154. I don't think fixing that issue alone would solve your request, but it is a prereq. Please submit a feature request issue with your example so we can track it at https://github.com/pester/Pester/issues – Frode F. Jul 24 '23 at 09:59
  • @FrodeF. Thank you for your reply. We've changed the code to a `foreach`-loop as a (valid) workaround – mhu Aug 04 '23 at 14:28

0 Answers0