pester / Pester

Pester is the ubiquitous test and mock framework for PowerShell.
https://pester.dev/
Other
3.07k stars 469 forks source link

Pester Should -Invoke -Scope "It" not working as expected #2453

Closed sheppyh closed 3 months ago

sheppyh commented 3 months ago

Checklist

What is the issue?

The following code demonstrates the issue. The test "Should not invoke FunctionToBeMocked" fails.

If I remove the BeforeEach block from Describe, the "Should not invoke FunctionToBeMocked" test passes.

The test appears to ignore "-Scope It" and the invocation count is not reset.

Expected Behavior

The test should pass, as the scope of the Should -Invoke is set to "It".

Steps To Reproduce

function FunctionToBeMocked {
    Write-Host "Function to be mocked"
}

function FunctionToTest {
    param(
        # Call FunctionToBeMocked?
        [Parameter()]
        [switch]
        $Call
    )

    if ($Call) {
        FunctionToBeMocked
    }
}

Describe "FunctionToTest" {
    BeforeEach {
        Mock FunctionToBeMocked {}

        FunctionToTest -Call
    }
    It "Should invoke FunctionToBeMocked" {
        Should -Invoke FunctionToBeMocked
    }
    Context "When calling FunctionToTest without -Call" {
        It "Should not invoke FunctionToBeMocked" {
            Mock FunctionToBeMocked {}

            FunctionToTest #-Call

            Should -Not -Invoke FunctionToBeMocked -Scope It
        }
    }
}

Output:

Starting discovery in 1 files.
Discovery found 2 tests in 22ms.
Running tests.
[-] FunctionToTest.Context.Should invoke FunctionToBeMocked 21ms (19ms|2ms)
 Expected FunctionToBeMocked not to be called exactly 1 times, but it was
 at Should -Not -Invoke FunctionToBeMocked -Scope It, C:\Users\user\Git\Private\Test-Pester.ps1:33
 at <ScriptBlock>, C:\Users\user\Git\Private\Test-Pester.ps1:33
Tests completed in 202ms
Tests Passed: 1, Failed: 1, Skipped: 0 NotRun: 0

Describe your environment

Pester version : 5.5.0 C:\Program Files\WindowsPowerShell\Modules\Pester\5.5.0\Pester.psm1 PowerShell version : 5.1.20348.2400 OS version : Microsoft Windows NT 10.0.20348.0

Possible Solution?

No response

fflaten commented 3 months ago

In Pester BeforeEach and AfterEach are considered part of the test (It scope). BeforeAll and AfterAll are part of the parent block.

See https://pester.dev/docs/usage/mocking#counting-mocks-depends-on-placement

Btw: I'd recommend defining mocks in a BeforeAll to avoid overwriting it multiple times. Might be a shortcut for the repro but worth mentioning just in case.