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 <ScriptBlock>, 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.

Upvotes: 0

Views: 56

Answers (1)

Venkatesan
Venkatesan

Reputation: 10455

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.

You can use the below PowerShell commands(script) to list the azure storage tables using Pester framework.

Command:

Describe "Azure Storage Account Operations Test" {

    # Mock the sensitive values to avoid real authentication
    BeforeAll {
        $appId = "xxx"
        $tenantId = "xxxx"
        $clientSecret = ".xxxx"  

        # 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 {
            return $mockContext
        }

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

    # 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" {
        $storageAccountName = "venkat326123"
        $context = New-AzStorageContext -StorageAccountName $storageAccountName
        $table = Get-AzStorageTable -Context $context

        # Assert that the table is not null
        $table | Should -Not -Be $null
        if ($table -eq $null) {
            throw "Table should not be null"
        }
        
        # Check the table name
        $table.Name | Should -Be "table1"

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

Output:

PS C:\Windows\system32> Invoke-Pester -Path "C:\Users\Documents\I010.Tests.ps1" -OutputFormat NUnitXml -OutputFile "C:\Users\Documents\TestResults.xml"
WARNING: You are using Legacy parameter set that adapts Pester 5 syntax to Pester 4 syntax. This parameter set is deprecated, and does not work 100%. The -Strict and -PesterOption parameters are ignor
ed, and providing advanced configuration to -Path (-Script), and -CodeCoverage via a hash table does not work. Please refer to https://github.com/pester/Pester/releases/tag/5.0.1#legacy-parameter-set 
for more information.

Starting discovery in 1 files.
Discovery found 2 tests in 12ms.
Running tests.
Mocked Connect-AzAccount called
[+] C:\Users\Documents\I010.Tests.ps1 169ms (95ms|65ms)
Tests completed in 173ms
Tests Passed: 2, Failed: 0, Skipped: 0, Inconclusive: 0, NotRun: 0

enter image description here

Xml file:

<?xml version="1.0" encoding="utf-8" standalone="no"?>
<test-results xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="nunit_schema_2.5.xsd" name="Pester" total="2" errors="0" failures="0" not-run="0" inconclusive="0" ignored="0" skipped="0" invalid="0" date="2024-09-20" time="11:51:01">
  <environment clr-version="4.0.30319.42000" user-domain="FAREAST" cwd="C:\Windows\system32" platform="Microsoft Windows 11 Pro|C:\Windows|\Device\Hxxxx\Partition3" machine-name="xxxx" nunit-version="2.5.8.0" os-version="10.0.22631" user="xxx" />
  <culture-info current-culture="en-IN" current-uiculture="en-US" />
  <test-suite type="TestFixture" name="Pester" executed="True" result="Success" success="True" time="0.1732" asserts="0" description="Pester">
    <results>
      <test-suite type="TestFixture" name="C:\Users\xxxx\Documents\I010.Tests.ps1" executed="True" result="Success" success="True" time="0.1732" asserts="0" description="C:\Users\xxx\Documents\I010.Tests.ps1">
        <results>
          <test-suite type="TestFixture" name="Azure Storage Account Operations Test" executed="True" result="Success" success="True" time="0.1157" asserts="0" description="Azure Storage Account Operations Test">
            <results>
              <test-case description="Should connect to Azure with the provided service principal" name="Azure Storage Account Operations Test.Should connect to Azure with the provided service principal" time="0.0442" asserts="0" success="True" result="Success" executed="True" />
              <test-case description="Should retrieve the Azure Storage Table" name="Azure Storage Account Operations Test.Should retrieve the Azure Storage Table" time="0.0552" asserts="0" success="True" result="Success" executed="True" />
            </results>
          </test-suite>
        </results>
      </test-suite>
    </results>
  </test-suite>
</test-results>

Upvotes: 0

Related Questions