locked
question around how to unit test with pester a powershell function that gathers event log errors RRS feed

  • Question

  • Hi there

    Im a newcomer to the Pester testing framework for powershell and have a question about how to unit test a powershell function I have written that gathers errors or warnings from system or security logs - this is because it is a requirement when submitting this into source control - I have written (what I think is an acceptance test in pester for the script) but unsure how one would go about writing a unit test for this - the code is not really changing anything in the environment only pulling error entries from 1 or multiple servers and outputting in out-gridview.  The pester test I have written - tests 1) that the properties returned are correct and 2) that 50 rows of data are returned and 3) tests with both parameter and pipeline input - but im not sure how you would unit test this as from my reading on the subject (and limited knowledge) unit tests are supposed to be isolated and not make actual live calls to a server or service outside the unit test - here is the actual script - and the pester test I have written so far: any help on this would be appreciated

    function Get-EventData
    {
    
        [CmdletBinding()]
    
        param(
        [Parameter(
        Mandatory=$true,
        ValueFromPipeline = $true
    
        )]
        [String[]]$targetmachine,
    
    
        [parameter( Mandatory=$true, Position=1)]
        [ValidateSet("Application","System")]
        [string]$log,
    
        [parameter( Mandatory=$true, Position=2)]
        [ValidateSet("Error","Warning")]
        [string]$eventtype,
    
        [parameter( Mandatory=$true, Position=3)]
        [ValidateNotNull()]
        [System.Management.Automation.Credential()]
        [System.Management.Automation.PSCredential]$credential
    
        )
    
    
            begin{
    
    $machinelogs=@()
    
        }
    
        process{
    
    
       foreach($target in $targetmachine)
       {
    
               try{
    
                        $evt = Invoke-Command -ComputerName $target `
                        -ScriptBlock{
    
                            Get-EventLog -LogName $using:log -EntryType $using:eventtype -Newest 50
    
                } -Credential $credential -ErrorAction Stop
                }catch{Write-Host -ForegroundColor Green "Failed to connect to remote server $target";continue}
    
    
                $evt | % {
    
                     $obj = New-Object psobject
                     $obj | Add-Member NoteProperty MachineName $_.pscomputername
                     $obj | Add-Member NoteProperty TimeGenerated $_.timegenerated
                     $obj | Add-Member NoteProperty EventID $_.EventID
                     $obj | Add-Member noteproperty EntryType $_.entrytype
                     $obj | Add-Member NoteProperty Source $_.source
                     $obj | Add-Member NoteProperty Message $_.message
                     $machinelogs += $obj
                    }
    
                $evt = $null
        }
    
        }  #endprocess
    
       end{
    
                $machinelogs | Out-GridView -Title "Machine Events" -PassThru
        }
    
    }

    and here is the pester test

    # Dot Source the function to load into memory
    . $PSScriptRoot\Get-EventData.ps1
    
    Describe 'Get-EventData Acceptance Tests' -Tags 'Acceptance' {
    
        $calls = 'parameter','pipeline'    # user to validate use of parameter or pipeline call to function
        foreach($call in $calls)
        {
                if($call -eq 'parameter')
                {
                    $eventdata = Get-EventData -targetmachine exchangeserver -log Application -eventtype Error -credential admin    
                }
                else
                {
                    $eventdata = 'exchangeserver' | Get-EventData -log Application -eventtype Error -credential admin
                }
    
        
                $rowNum = 0
                foreach($event in $eventdata)
                {
                    $rowNum++
                    Context "Event $rowNum has the correct properties" {
    
                        #Load array with properties that should be present
                        $properties = ('MachineName','TimeGenerated','EventID', 'EntryType',
                                        'Source', 'Message')
    
                        foreach($property in $properties)
                        {
                            It "EventData $rownum should have a property of $property" {
    
                            [bool]($event.PSObject.Properties.Name -match $property) |
                                Should Be $true
                        }
                  } #foreach
    
                    } #end context block
    
                } # foreach ($event in $eventdata)
    
                Context " 50 rows should be returned per Server" {  # context block to validate 50 rows returned
                    It "Count Should be equal to 50" {
                
                        $eventdata.count | Should Be 50
    
                    }
    
                }# end context block
        } # end calls foreach loop
    $rowNum = 0
    }#end describe block

    Monday, February 5, 2018 9:45 PM

Answers