Search code examples
powershellunit-testingazure-storageazure-powershellpester

Pester Unit Test for Get-AzureBlobStorage


I am trying to write a unit for a simple Azure function in Powershell

function Get-AzureBlobStorage {
    param (
        [Parameter(Mandatory)]
        [string]$ContainerName,
        [Parameter(Mandatory)]
        [string]$Blob,
        [Parameter(Mandatory)]
        $Context
    )
    try {
        return (Get-AzStorageBlob -Container $ContainerName -Context $Context -Blob $Blob)
    }
    catch {
        Write-Error "Blobs in Container [$ContainerName] not found"

    }

Unit test

   Context 'Get-AzureBlobStorage' {
        It 'Should be able to get details to Blob Storage account without any errors' {
                $ContainerName = 'test'
                $Blob="test-rg"
                $Context = "test"
                Mock Get-AzStorageBlob { } -ModuleName $moduleName
                Get-AzureBlobStorage -ContainerName $ContainerName -Blob $Blob -Context $Context -ErrorAction SilentlyContinue -ErrorVariable errors
                $errors.Count | Should -Be 0
            }
}

But i was not able to get it to work. I am getting ht following error,

Cannot process argument transformation on parameter 'Context'. Cannot convert the "test" value of type "System.String" to type "Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext". 

My question is how to get such values as context. I have several other functions where one of the parameters is always some complex object. What is the best way to write unit test for such functions


Solution

  • Your issue is because the input of the Get-AzStorageBlob cmdlet expects a specific type of object for -Context. You can get Pester to remove the strong type on the input by using Mock with -RemoveParameterType.

    Here's how I'd test your function:

    Describe 'Tests' {
    
        Context 'Get-AzureBlobStorage returns blob' {
            
            BeforeAll {
                Mock Get-AzStorageBlob {} -RemoveParameterType Context
            }
    
            It 'Should be able to get details to Blob Storage account without any errors' {
    
                $ContainerName = 'test'
                $Blob = "test-rg"
                $Context = "test"
    
                Get-AzureBlobStorage -ContainerName $ContainerName -Blob $Blob -Context $Context -ErrorVariable errors
                Assert-MockCalled Get-AzStorageBlob
            }
        }
    
        Context 'Get-AzureBlobStorage returns error' {
    
            BeforeAll {
                Mock Get-AzStorageBlob { throw 'Error' } -RemoveParameterType Context
                Mock Write-Error { }
            }
    
            It 'Should return an error via Write-Error' {
    
                $ContainerName = 'test'
                $Blob = "test-rg"
                $Context = "test"
    
                Get-AzureBlobStorage -ContainerName $ContainerName -Blob $Blob -Context $Context
                Assert-MockCalled Write-Error -Times 1 -Exactly
            }
        }
    }