Use Multiple Mocks to Test Function?

This topic contains 1 reply, has 2 voices, and was last updated by  Adam Bertram 5 months ago.

  • Author
    Posts
  • #70643

    John
    Participant

    Hi,
    I'm a newbie to Pester so please forgive me if this has been answered already. I want to run multiple unit tests on a PowerShell function, providing a range of mocks to exercise the function. Below is the function and test code I've written. I'd like to mock Get-WASJob multiple times, providing a separate mock to each unit test.
    How do I do this?
    Thanks,
    John

    Function GetWASJob {
        param ( [string]$project, [string]$job, [string]$os, [string]$runtype )
        $runjob = Get-WASJob -ProjectName $project -JobName $job -ErrorAction Stop
    
        #Check if the WAS job is valid
        if ($runjob -and $runjob.JobName) {
            WriteToLog "GetWASJob: Returned a valid WAS job" $logfile
        }
        else {
            WriteToLog "GetWASJob: Valid WAS job not returned...Quit" $logfile
            break
        }
        return $runjob
    }

    Pester code to test the above function:

    Describe "GetWASJob" {
        Context "Just Testing..." {
            Mock Get-WASJob {
                $obj = New-MockObject -Type 'Microsoft.Assessments.WAS.PowerShell.WASJob'
                $obj | Add-Member -Type NoteProperty -Name 'JobName' -Value 'PesterJob1' -Force
                $obj | Add-Member -Type NoteProperty -Name 'Tags' -Value 'PesterTag1' -Force
                return $obj
            }
    
        	$result = GetWASJob -project "Project1" -job "Job1" -os "Windows10" -runtype "Production"
    
    	    It "Verified that all mocks were called" {
    	        Assert-VerifiableMocks
    	    }
    	    It "Checks that a valid job object was returned" {
                $result.JobName | Should Be "PesterJob1"
    	    }
        }
    }
  • #70684

    Adam Bertram
    Moderator

    Hi John,

    You should create multiple mocks with different parameter filters. This will allow you to have your Get-WasJob mocks to return different objects.

    Here's an example.

    Mock -Verifiable 'Get-WASJob' {
                $obj = New-MockObject -Type 'Microsoft.Assessments.WAS.PowerShell.WASJob'
                $obj | Add-Member -Type NoteProperty -Name 'JobName' -Value 'PesterJob1' -Force
                $obj | Add-Member -Type NoteProperty -Name 'Tags' -Value 'PesterTag1' -Force
                return $obj
            } -ParameterFilter { $Project -eq 'Project1' -and $Job -eq 'Job1' -and $Os -eq 'Windows10 -and $RunType -eq 'Production' }
    
    Mock -Verifiable 'Get-WASJob' {
                $obj = New-MockObject -Type 'Microsoft.Assessments.WAS.PowerShell.WASJob'
                $obj | Add-Member -Type NoteProperty -Name 'JobName' -Value 'PesterJob2' -Force
                $obj | Add-Member -Type NoteProperty -Name 'Tags' -Value 'PesterTag2' -Force
                return $obj
            } -ParameterFilter { $Project -eq 'Project2' -and $Job -eq 'Job2' -and $Os -eq 'Windows10 -and $RunType -eq 'Production' }

    Once you've got the mocks created and "tagged" as verifiable, you can then run

    Assert-VerifiableMocks

    to assert that each of them was called. Since you've set a parameter filter on each of the mocks, you can then trust that if all of the mocks were called then that means each of the parameter sets were used on those mocks.

You must be logged in to reply to this topic.