pester / Pester

Pester is the ubiquitous test and mock framework for PowerShell.
https://pester.dev/
Other
3.11k stars 473 forks source link

Alias for commands from external modules can not be mocked #1462

Open bigbearzhu opened 4 years ago

bigbearzhu commented 4 years ago

1. General summary of the issue

When alias is created on certain commands from external module, you can't Mock it.

2. Describe Your Environment

Pester version : 4.10.1 C:\Program Files\WindowsPowerShell\Modules\Pester\4.10.1\Pester.psd1 PowerShell version : 5.1.18362.628 OS version : Microsoft Windows NT 10.0.18363.0

We only have Az module installed, but enabled azure rm aliases through Enable-AzureRmAlias -Scope LocalMachine. Originally I found this issue when run Mock Get-AzureKeyVaultSecret, it throws alias not found error. However, I found it more generic. See this test below:

Describe "mock alias" {
    New-Alias -Name SomeAlias -Value Get-AzKeyVaultSecret
    Mock SomeAlias
}

3. Expected Behavior

It should be able to mock an alias, if you replace Get-AzKeyVaultSecret with Get-Item it worked.

4.Current Behavior

Can't find the alias. However, if you run the alias once, then the test will pass.

Pester v4.10.1
Executing all tests in '.\AliasMock.Tests.ps1'

Executing script .\AliasMock.Tests.ps1

  Describing mock alias
    [-] Error occurred in Describe block 0ms
      CommandNotFoundException: Could not find Command SomeAlias
      at Validate-Command, C:\Program Files\WindowsPowerShell\Modules\Pester\4.10.1\Functions\Mock.ps1: line 914
      at Mock, C:\Program Files\WindowsPowerShell\Modules\Pester\4.10.1\Functions\Mock.ps1: line 215

5. Possible Solution

6. Context

nohwnd commented 4 years ago

Is that because the module is not loaded yet? Could you try loading the module explicitly before trying to mock it?

bigbearzhu commented 4 years ago

adding Import-Module Az does work. Is that possible to make the module automatically loaded when you mock similar how powershell loads modules from modules directories when a command from that module is called?

nohwnd commented 4 years ago

I see that get-command <alias> loads the module that has the alias into the session. Could you try calling Get-Command Get-AzureKeyVaultSecret instead of Import-Module in a clean powershell instance to confirm calling it inside of mock would solve your problem?

bigbearzhu commented 4 years ago

Hmm, I don't see this behaviour. See the console output below. The actual module Az.KeyVault is only loaded when Get-Command is run on the actual command, not the alias.

PS H:\> Get-Command Get-AzureKeyVaultSecret

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           Get-AzureKeyVaultSecret

PS H:\> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     1.7.0      Az.Accounts                         {Add-AzEnvironment, Clear-AzContext, Clear-AzDefault, Conn...
Script     0.0        chocolateyProfile                   {TabExpansion, Update-SessionEnvironment, refreshenv}
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Con...
Manifest   3.0.0.0    Microsoft.PowerShell.Security       {ConvertFrom-SecureString, ConvertTo-SecureString, Get-Acl...
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Manifest   3.0.0.0    Microsoft.WSMan.Management          {Connect-WSMan, Disable-WSManCredSSP, Disconnect-WSMan, En...
Script     2.0.0      PSReadline                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PS...

PS H:\> Get-Command Get-AzKeyVaultSecret

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Cmdlet          Get-AzKeyVaultSecret                               1.4.0      Az.KeyVault

PS H:\> Get-Module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Script     1.7.0      Az.Accounts                         {Add-AzEnvironment, Clear-AzContext, Clear-AzDefault, Conn...
Script     1.4.0      Az.KeyVault                         {Add-AzKeyVaultCertificate, Add-AzKeyVaultCertificateConta...
Script     0.0        chocolateyProfile                   {TabExpansion, Update-SessionEnvironment, refreshenv}
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Con...
Manifest   3.0.0.0    Microsoft.PowerShell.Security       {ConvertFrom-SecureString, ConvertTo-SecureString, Get-Acl...
Manifest   3.1.0.0    Microsoft.PowerShell.Utility        {Add-Member, Add-Type, Clear-Variable, Compare-Object...}
Manifest   3.0.0.0    Microsoft.WSMan.Management          {Connect-WSMan, Disable-WSManCredSSP, Disconnect-WSMan, En...
Script     2.0.0      PSReadline                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PS...
nohwnd commented 4 years ago

Okay thanks, I only tested it quickly, that is why I wanted to confirm. Please use the Import-Module workaround in the meantime. This might take a while to fix. :)

bigbearzhu commented 4 years ago

Thanks no pressure. Import-Module works!

On 6 Mar 2020, at 5:32 pm, Jakub Jareš notifications@github.com wrote:

 Okay thanks, I only tested it quickly, that is why I wanted to confirm. Please use the Import-Module workaround in the meantime. This might take a while to fix. :)

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.