You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#4564 made class methods' mock instances independent, but it overlooked some important edge cases:
Resetting an automocked constructor causes calling that constructor to no longer isolate its called members
Resetting/overriding the implementation of an isolated function detaches it entirely from the parent, causing the prototype method to no longer register mock calls
This is causing a lot of headaches while I'm trying to update our version of Vitest past 1.0.0 as we used prototypes and resetAllMocks all over the place.
The second point I can forego a fix for if necessary, since I can rewrite most of our tests using instance accessing instead of prototypes (i.e. foo.bar instead of Foo.prototype.bar), but the first point is really painful, and both are very counterintuitive.
// file: src/__tests__/class.test.tsimport{expect,test,vitest}from"vitest";import{TestClass}from"../class.js";vitest.mock("../class.js");test("isolation",()=>{constinst1=newTestClass();// Normally, using the prototype counts the same calls as the instance.voidinst1.doAThing();expect(inst1.doAThing).toHaveBeenCalledTimes(1);expect(TestClass.prototype.doAThing).toHaveBeenCalledTimes(1);// However, mocking the implementation of the instance detaches calls from the// prototype.vitest.mocked(inst1.doAThing).mockReturnValue(21);voidinst1.doAThing();expect(inst1.doAThing).toHaveBeenCalledTimes(2);expect.soft(TestClass.prototype.doAThing).toHaveBeenCalledTimes(2);// Resetting mocks should restore back to the original behavior, but it doesn't:vitest.resetAllMocks();voidinst1.doAThing();expect(inst1.doAThing).toHaveBeenCalledTimes(1);expect.soft(TestClass.prototype.doAThing).toHaveBeenCalledTimes(1);// This is once again decoupled.// And now the constructor shim is also broken, so these two instances are no longer isolated.constinst2=newTestClass();constinst3=newTestClass();expect.soft(inst2.doAThing).not.toBe(inst3.doAThing);expect.soft(vitest.mocked(inst2.doAThing).mock).not.toBe(vitest.mocked(inst3.doAThing).mock);voidinst2.doAThing();expect(inst2.doAThing).toHaveBeenCalledTimes(1);expect.soft(inst3.doAThing).toHaveBeenCalledTimes(0);});
Describe the bug
#4564 made class methods' mock instances independent, but it overlooked some important edge cases:
This is causing a lot of headaches while I'm trying to update our version of Vitest past 1.0.0 as we used prototypes and
resetAllMocks
all over the place.The second point I can forego a fix for if necessary, since I can rewrite most of our tests using instance accessing instead of prototypes (i.e.
foo.bar
instead ofFoo.prototype.bar
), but the first point is really painful, and both are very counterintuitive.Reproduction
System Info
Used Package Manager
npm
Validations
The text was updated successfully, but these errors were encountered: