Closed buck06191 closed 5 months ago
Hi @buck06191! I'm opposed to verifyAllWhenMocksCalled
on philosophical and technical grounds. See #10 for more details and background.
Philosophical
I think reliance on verifyAllWhenMocksCalled
makes your test suite (and, by extension, your code under test) worse by tightly coupling your tests to your implementations and hiding useful design feedback from your tests:
Technical
Implementating verifyAllWhenMocksCalled
requires adding global state to this library, which would then require cleanup. This is not something I'm willing to add to this library, since it would put restrictions on usage and introduce weird cleanup footguns
vitest-when
attaches all state to individual vi.fn()
mocks for automatic cleanup by Vitest itselfjest-when
, which requires the use of resetAllWhenMocks()
Userland
Not everyone has the same stubbing philosophy as me, and that's ok! While I am unwilling to implement this feature in vitest-when
, I am interested in making it so that others, if they so chose, could implement this feature on top of vitest-when
in their own suites
Personally, I think verifyAllMWhenMocksCalled
is a poor testing practice, but I can see its usefulness as a test debugging tool. To that end, I've been working on #11 to add the ability to inspect individual stubs. I think the debug
function should return enough information to determine if an individual stub has been called.
Are there any APIs you could imagine that would help implement a stub registry in your suite - that you would be responsible for managing cleanup of yourself - to give yourself the ability to loop through all your stubs to check them?
I think a fixture like this in your own codebase could work to replicate verifyAllWhenMocksCalled
:
// when.ts
import { afterEach, expect } from 'vitest'
import { when as baseWhen } from 'vitest-when'
const mockRegistry = new Set()
export const when: typeof baseWhen = (spy, options) => {
const result = baseWhen(spy, options)
mockRegistry.add(spy)
return result
}
afterEach(() => {
const mocks = [...mockRegistry]
mockRegistry.clear()
for (const mock of mocks) {
expect(mock).toHaveBeenCalled()
}
})
Then, in your tests, import when
from your fixture file instead of directly from vitest-when
@buck06191 thanks for taking the time to write this request! After giving it some additional thought over the weekend - and after landing #11 - I don't think this feature is a good fit for this library. I'd like to keep vitest-when
pretty laser-focused on adding a conditional stubbing API to vi.fn()
. I think call assertions and more frameworky features - like tracking the state of all mocks - are best left to userland and/or vitest
itself.
Let me know if the above example is able to get you where you need to go, or if there are additional stub-level APIs that could be added to help you implement what you're trying to do
What
In
jest-when
there's a feature we use at our company that verifies all of thewhen
mocks are called by the end of a test -https://github.com/timkindberg/jest-when/blob/master/src/when.js#L216In order for us to migrate to vitest it would be really good to have this added in to
vitest-when
.Do you think this is something you'd consider adding in? We could look at raising a PR ourselves as a proposal if that's the case