powershellpester

How to get Pester Mocks working in a script


I not able to get Pester 5.5.0 Mocks working. I have defined a Mock for Get-Date in the Describe block but when the tests run it does not appear to be invoked.

MyFunction.ps1

function Get-CurrentDate {
    return Get-Date
}

MyFunction.test.ps1

BeforeAll {
    . $PSCommandPath.Replace('.Tests.ps1', '.ps1')
}

Describe 'Get-CurrentDate Tests' {
    Mock Get-Date { return [DateTime]'2023-01-01' }

    It 'returns the mocked date' {
        $expected = [DateTime]'2023-01-01'
        $actual = Get-CurrentDate
        $actual | Should -Be $expected
    }
}

Output:

Invoke-Pester .\MyFunction.Tests.ps1

Starting discovery in 1 files. Discovery found 1 tests in 1.92s. Running tests. [-] Get-CurrentDate Tests.returns the mocked date 2.24s (2.03s|213ms) Expected 2023-01-01T00:00:00.0000000, but got 2023-11-27T16:42:33.7602327+01:00. at $actual | Should -Be $expected, C:\MyFunction.Tests.ps1:12 at , C:\MyFunction.Tests.ps1:12

Is the problem the scope?


Solution

  • In Pester 5 Mocks need to be defined either in a BeforeAll, BeforeEach or in the It block itself. This should work:

    BeforeAll {
        . $PSCommandPath.Replace('.Tests.ps1', '.ps1')
    }
    
    Describe 'Get-CurrentDate Tests' {
        
        BeforeAll {
            Mock Get-Date { return [DateTime]'2023-01-01' }
        }
    
        It 'returns the mocked date' {
            $expected = [DateTime]'2023-01-01'
            $actual = Get-CurrentDate
            $actual | Should -Be $expected
        }
    }
    

    Note also that Mocks are now scoped based on their placement: https://pester.dev/docs/usage/mocking#mocks-are-scoped-based-on-their-placement

    Mocks are no longer effective in the whole Describe / Context in which they were placed. Instead they will default to the block in which they were placed.