Error on Azure Storage Tables using Peter Test Framework by adding PowerShell commands

I’m getting error while trying to list the azure storage tables using Pester framework. The same commands in PowerShell are working fine. My requirement is I want to convert the PowerShell commands as a test in Pester Test Framework. I am connecting to Azure using Service Principal. The commands are:

$appId = "<app/client Id>"

$tenantId = "<tenant id>"

$clientSecret = "<client secret>"

$secureClientSecret = ConvertTo-SecureString -String $clientSecret -AsPlainText -Force

$psCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $appId, $secureClientSecret

Connect-AzAccount -ServicePrincipal -Credential $pscredential -Tenant $tenantId

$resourceGroupName = "dev-integrationbus"

$storageAccountName = "devisstorage"

$tableName = "InterfaceLogs"

$context = New-AzStorageContext -StorageAccountName $storageAccountName

$storageTable = Get-AzStorageTable -Name $tableName -Context $context

Get-AzStorageTable -Context $context | select Name
 

My Pester test script code is:

# Import Pester and Az Storage modules
Import-Module Pester
Import-Module Az.Storage

# Define the Pester test script
Describe "Azure Storage Account Operations Test" {

    # Mock the sensitive values to avoid real authentication
    BeforeAll {
        $appId = "<app/client Id>"
        $tenantId = "<tenant id>"
        $clientSecret = "<client secret>"  

    # Mock value for client secret in tests
        $secureClientSecret = ConvertTo-SecureString -String $clientSecret -AsPlainText -Force
        $psCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $appId, $secureClientSecret
    }

    # Mock Azure cmdlets in the correct scope
    BeforeEach {
        # Mock Connect-AzAccount command
        Mock -CommandName Connect-AzAccount {
            Write-Host "Mocked Connect-AzAccount called"
        }

        # Mock New-AzStorageContext to return a more realistic mock for IStorageContext
        Mock New-AzStorageContext {
            $mockContext = New-Object -TypeName PSObject
            $mockContext | Add-Member -MemberType NoteProperty -Name "StorageAccountName" -Value "mockStorageAccount"
            $mockContext | Add-Member -MemberType NoteProperty -Name "ContextType" -Value "Storage"
            return $mockContext
        }

        # Mock Get-AzStorageTable command
        Mock -CommandName Get-AzStorageTable {
            return [pscustomobject]@{
                Name = "InterfaceLogs"
            }
        }
    }

    # Test if Connect-AzAccount runs successfully
    It "Should connect to Azure with the provided service principal" {
        Connect-AzAccount -ServicePrincipal -Credential $psCredential -Tenant $tenantId

        # Assert the Connect-AzAccount command was called
        Assert-MockCalled Connect-AzAccount -Exactly 1 -Scope It
    }

    # Test storage table context creation and table retrieval
    It "Should retrieve the Azure Storage Table" {
        # Act
        $context = New-AzStorageContext -StorageAccountName "devisstorage"
        $table = Get-AzStorageTable -Context $context

        # Assert
        $table | Should -Not -BeNullOrEmpty
        $table.Name | Should -Be "InterfaceLogs"

        # Verify if the mocks were called correctly
        Assert-MockCalled New-AzStorageContext -Exactly 1 -Scope It
        Assert-MockCalled Get-AzStorageTable -Exactly 1 -Scope It
    }
}

By running: Invoke-Pester -Path .\I010.Tests.ps1 -OutputFormat NUnitXml -OutputFile C:\Users\srikant\Desktop\PesterReport\TestResults.xml

The error it shows is:

Starting discovery in 1 files. Discovery found 2 tests in 54ms. Running tests. Mocked Connect-AzAccount called [-] Azure Storage Account Operations Test.Should retrieve the Azure Storage Table 68ms (64ms|5ms) PSInvalidCastException: Cannot convert the “@{StorageAccountName=mockStorageAccount; ContextType=Storage}” value of type “System.Management.Automation.PSCustomObject” to type “Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext”. ArgumentTransformationMetadataException: Cannot convert the “@{StorageAccountName=mockStorageAccount; ContextType=Storage}” value of type “System.Management.Automation.PSCustomObject” to type “Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext”. ParameterBindingArgumentTransformationException: Cannot process argument transformation on parameter ‘Context’. Cannot convert the “@{StorageAccountName=mock StorageAccount; ContextType=Storage}” value of type “System.Management.Automation.PSCustomObject” to type “Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext”. at , C:\Users\srikant\Desktop\Automation_Sept13_Clone\tst\testProjects\BasicTests\folder1\I010.Tests.ps1:52 Tests completed in 286ms Tests Passed: 1, Failed: 1, Skipped: 0, Inconclusive: 0, NotRun: 0

Here, I am looking to try the same PowerShell commands given above using Pester Framework as a test script and fetch the list of azure storage tables within Azure Storage Account.

Hi, welcome to the forum :wave:

Looking for posts with similar errors, the problem appears to be that Get-AzStorageTable is expecting an object of type IStorageContext but when you mock New-AzStorageContext you’re returning a PSObject.

Try New-MockObject (not tested).

Mock New-AzStorageContext {
    $MockObjectParam = @{
        Type = 'Microsoft.Azure.Commands.Common.Authentication.Abstractions.IStorageContext'
        Properties = @{
            StorageAccountName = 'mockStorageAccount'
            ContextType        = 'Storage'
        }
    }    
    $MockContext = New-MockObject @MockObjectParam
    return $MockContext
}

By the way, while it’s great you formatted your code correctly in your first post (well done!), errors can also be wrapped in backticks which really helps with readability.

1 Like