Search code examples
powershelltestingpester

Mocking wiht Pester


I am an utter newbie regarding PowerShell and Pester. I followed some trainings about Pester and how to create tests but I am not very clear about it. I have a small function that checks the Hash of an online PDF and I have written a test for it but I am not sure if I am doing it the right way. I would appreciate any help/explanation.

Function to Test:

function Get-FileHashFromUrl {
    try {
        $wc = [System.Net.WebClient]::new()
        Get-FileHash -InputStream($wc.OpenRead("https://example.com/apps/info.pdf"))
    }
    catch {
        return $Error
    }
}

Test with Perster 5.3

BeforeAll {
    . $PSScriptRoot\myScript.ps1
}
Describe "Get-FileHashFromUrl" {
    It 'Get the PDF Hash from Url' {
        Mock -CommandName Get-FileHashFromUrl -MockWith { $hash }
        $hash = '7EE8DB731BF3E5F7CF4C8688930D1EB079738A3372EE18C118F9F4BA22064411'
        Get-FileHashFromUrl | Should -Be $hash
        Assert-MockCalled Get-FileHashFromUrl -Times 1 -Exactly
    }
}

Solution

  • I'm not sure I'd be using the Mock function in your test as mocking allows you to fake or alter the behavior/returned data of an existing command and I'm guessing you want to really test the file hash returned rather that faking it.

    Mocking would be useful if you wanted to purposely test a failure for example (by getting the mocked command to return the wrong hash), or to simulate a command that you can't run in a particular environment.

    Assuming that the mocked function was removed, your test wouldn't work quite as expected because your Get-FileHashFromUrl function is returning the complete object that Get-FileHash returns rather than just the hash:

    File hash object

    You'd either want to change your function to return just the hash, like so:

    function Get-FileHashFromUrl {
        try {
            $wc = [System.Net.WebClient]::new()
            return (Get-FileHash -InputStream($wc.OpenRead("https://example.com/apps/info.pdf"))).Hash
        }
        catch {
            return $Error
        }
    }
    

    Or, change your test to:

    BeforeAll {
        . $PSScriptRoot\myScript.ps1
    }
    Describe "Get-FileHashFromUrl" {
        It 'Get the PDF Hash from Url' {
            $hash = '7EE8DB731BF3E5F7CF4C8688930D1EB079738A3372EE18C118F9F4BA22064411'
            (Get-FileHashFromUrl).Hash | Should -Be $hash
        }
    }