Pester icon indicating copy to clipboard operation
Pester copied to clipboard

Mock Command with dynamic ValidateSet

Open StefanSchoof opened this issue 5 years ago • 3 comments

1. General summary of the issue

The Get-AzureRmContext defines a dynamic ValidateSet for the Name Parameter, that checks if the given Name is existing on the current Machine. Using the RemoveParameterValidation Parameter does not remove this check.

2. Describe Your Environment

Pester version     : 4.10.1 C:\Users\SSchoof\OneDrive\Dokumente\WindowsPowerShell\Modules\Pester\4.10.1\Pester.psd1
PowerShell version : 5.1.18362.752
OS version         : Microsoft Windows NT 10.0.18363.0

3. Expected Behavior

With the RemoveParameterValidation the ValidateSet of the Name Parameter is removed.

4.Current Behavior

Describe "Get-AzureRmContext" {
    Mock Get-AzureRmContext -RemoveParameterValidation Name
    It "Mocks the validate set" {
        Get-AzureRmContext -Name "ThisContextDoesNotExistOnThisMaschine"
    }
}
[-] Mocks the validate set 44ms
      ValidationMetadataException: Das Argument "ThisContextDoesNotExistOnThisMaschine" gehört nicht zu dem vom ValidateSet-Attribut angegebenen Satz "<all my existing contexts>". Geben Sie ein Argument an, das in dem Satz enthalten ist, und führen Sie dann den Befehl erneut aus. 
      ParameterBindingValidationException: Das Argument für den Parameter "Name" kann nicht überprüft werden. Das Argument "ThisContextDoesNotExistOnThisMaschine" gehört nicht zu dem vom ValidateSet-Attribut angegebenen Satz "<all my existing contexts>". Geben Sie ein Argument an, das in dem Satz enthalten ist, und führen Sie dann den Befehl erneut aus.

5. Possible Solution

Adding a layer of function

Describe "Get-AzureRmContext" {
    function GetAzureRmContext {
        param (
            [String] $Name
        )
        Get-AzureRmContext -Name $Name
    }
    Mock GetAzureRmContext
    It "Mocks the validate set" {
        GetAzureRmContext -Name "ThisContextDoesNotExistOnThisMaschine"
    }
}

6. Context

Mock the Get-AzureRmContext with the Name parameter, that is working independently of the current context of the VMs.

StefanSchoof avatar May 18 '20 14:05 StefanSchoof

I see this, what am I doing wrong?

Describing Get-AzureRmContext
  [-] Mocks the validate set 301ms
    ParameterBindingException: A parameter cannot be found that matches parameter name 'Name'.
    at <ScriptBlock>, C:\Users\jajares\Desktop\toplevelmock.tests.p1.ps1: line 4

PS C:\Projects\pester> (get-command Get-AzureRmContext).Module 


ModuleType Version    PreRelease Name                                ExportedCommands
---------- -------    ---------- ----                                ----------------
Script     5.8.3                 AzureRM.profile                     {Add-AzureRmEnvironment, Clear-AzureRmContext, Clear-AzureRmDefault, Connect-AzureRmAccount…}

nohwnd avatar May 19 '20 05:05 nohwnd

Thanks for the quick response.

Strange, I got a version below yours:

PS > (get-command Get-AzureRmContext).Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     5.8.2      AzureRM.profile                     {Add-AzureRmEnvironment, Clear-AzureRmContext, Clear-AzureRmDefault, Connect-AzureRmAccount...}

PS > (get-command Get-AzureRmContext).Parameters["Name"]


Name            : Name
ParameterType   : System.String
ParameterSets   : {[GetSingleContext, System.Management.Automation.ParameterSetMetadata]}
IsDynamic       : True
Aliases         : {}
Attributes      : {GetSingleContext, System.Management.Automation.ValidateSetAttribute}
SwitchParameter : False

The Documentation is also showing this parameter.

StefanSchoof avatar May 19 '20 05:05 StefanSchoof

Okay, found strange behavior. The AzureRm Module is replaced with the new Az module. I had currently not installed on my machine:

PS >Install-Module -Name Az -AllowClobber -Scope CurrentUser
PS > Get-AzContext
PS > Get-AzContext -Name "abc"
Get-AzContext: A parameter cannot be found that matches parameter name 'Name'.
PS > Connect-AzAccount
WARNING: To sign in, use a web browser to open the page https://microsoft.com/devicelogin and enter the code <code> to authenticate.
PS > Get-AzContext -Name "abc"
Get-AzContext: Cannot validate argument on parameter 'Name'. The argument "abc" does not belong to the set "<names of my azure subscriptions>" specified by the ValidateSet attribute. Supply an argument that is in the set and then try the command again.

It looks like the Name parameter is only valid after Connect is done.

In the code https://github.com/Azure/azure-powershell/blob/master/src/Accounts/Accounts/Context/GetAzureRMContext.cs#L82 there is something done with Name, which I do not understand fully. But I think the GetDynamicParameters https://github.com/Azure/azure-powershell/blob/4dc9cc1829829ceffedfa486a222906b0e9f1533/src/Accounts/Accounts/Context/GetAzureRMContext.cs#L118 is causing my problems.

StefanSchoof avatar May 19 '20 07:05 StefanSchoof