Skip to content

Don't require a verifiable mock that an inner-scope default mock shadows - #2751

Open
nohwnd wants to merge 2 commits into
mainfrom
fix/2672-verifiable-mock-override
Open

Don't require a verifiable mock that an inner-scope default mock shadows#2751
nohwnd wants to merge 2 commits into
mainfrom
fix/2672-verifiable-mock-override

Conversation

@nohwnd

@nohwnd nohwnd commented Jun 25, 2026

Copy link
Copy Markdown
Member

Fix #2672

A mock marked -Verifiable in an outer scope (Describe/Context) that you then override with another mock for the same command in an inner scope (It) could never pass Should -InvokeVerifiable: the inner mock handled the call, but Get-VerifiableBehaviors still collected the outer one and reported it as never invoked.

Get-VerifiableBehaviors now walks the scopes from the test outwards and drops a verifiable behavior when a closer scope has a default mock (one without a -ParameterFilter) for the same command - that default catches every call, so the outer behavior can't run and shouldn't be required. A verifiable mock that isn't shadowed like that is still required, same as before.

nohwnd and others added 2 commits June 25, 2026 23:27
…t mock shadows

A mock marked -Verifiable in an outer scope that is overridden by a mock for the same
command in a narrower scope could never pass Should -InvokeVerifiable, because
Get-VerifiableBehaviors still collected the outer behavior and reported it as never
invoked even though the inner mock handled every call.

Walk the scopes from the test outwards and drop a verifiable behavior when a closer
scope has a default mock (no -ParameterFilter) for the same command. A verifiable mock
that isn't shadowed is still required.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@nohwnd
nohwnd marked this pull request as ready for review September 5, 2026 08:45
@nohwnd

nohwnd commented Sep 5, 2026

Copy link
Copy Markdown
Member Author

Picked this back up. Merged main in, no conflicts, and it still does what it says.

The repro in #2672 is missing the outer Mock line, so I reconstructed it and checked several shapes against released 6.1.0 and against this branch:

6.1.0 this branch
outer verifiable in Context BeforeAll, inner verifiable in It fails passes
outer verifiable, inner not verifiable fails passes
outer verifiable at Describe level, inner default fails passes

One shape I got wrong on the first try, worth writing down so nobody else chases it: an outer verifiable mock with a -ParameterFilter and an inner default mock. That looks like it should be dropped too, but the call returns outer, not inner, because a parameterized behavior wins over a default one regardless of which scope it came from. So the outer mock does run there and requiring it is correct. Not a gap.

Also worth knowing: the bug only shows when the outer verifiable mock is never invoked before the overriding test. If an earlier It in the same Context already called it, the behavior is marked invoked and the override test passes even on 6.1.0. That is why a casual repro can look fine.

tst/Pester.Mock.RSpec.ts.ps1 40/40 and tst/functions/Mock.Tests.ps1 263/263 green.

Marking ready for review.

🤖

@nohwnd nohwnd added this to the 6.3.0 milestone Sep 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Verifiable Mock overridden in It block causes Should -InvokeVerifiable to fail

1 participant