-
-
Notifications
You must be signed in to change notification settings - Fork 6.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Scoped module initialization / cleanup #6174
Comments
So basically, within the scope, don't put modules which weren't in the cache into it? Seems simple enough, just check before putting it in here: https://github.com/facebook/jest/blob/16de9ac22f2817899990f15d535ecfb362952141/packages/jest-runtime/src/index.js#L322, and fix the Would you expect it to care about the mocked modules registry? Or core modules? |
I think it’s a bit trickier. They should be cached while within the scope. Because a stateful module may be required by more than one module. But they should be evicted as soon as we leave the scope.
Not sure what the specific considerations there need to be. My mental model for this is that when we go in the scope, we “fork” the registry to a sandbox. Whatever happens there (new modules loaded, new mocks set up) only affects the code inside the scope. When we exit the scope, we restore the previous registry. |
I like this idea and I'm trying implement it and better understand the problem. Would the proposed API be something like this? let counter;
jest.withResetModules(() => {
beforeEach(() => {
counter = require('./counter');
});
it('increments by one', () => {
counter.increment();
counter.increment();
expect(counter.getCount()).toBe(2)
});
it('and keeps incrementing', () => {
expect(counter.getCount()).toBe(3)
})
});
it('but it is cleared here', () => {
counter = require('./counter');
expect(counter.getCount()).toBe(1)
}); |
In my mind that won't work as |
Right! That’s exactly what I’ve been having trouble when trying to wrap my head around it... How do you imagine the API? |
That it has to happen within a single test case ( |
Awesome! Thanks, that is how I was originally thinking about It! I might put up a PoC tomorrow |
I was planning to call it inside beforeEach. |
it('foobar', () => {
myBeforeEach();
}); It just can't wrap around test declarations, as long as it runs within the context of a test I think we should be good 🙂 |
@rogeliog I actually prefer this proposal because I believe it gives a finer degree of control than in my proposed syntax. Like you point out, they are trying to solve the same problem, but this way might solve it more elegantly! |
Btw, if there's a working proof of concept, let me know and I can give it a try in a real codebase and give my feedback. |
Hey got into the use case where I would love if I am able to reset just a single module. I see a commit around 1 month ago. Can I please know when will it be available for us to use or if it is already rolled out (though I don't see anything in the documentation) ? |
Nothing is rolled out, but you can check the pr linked above if you want :) |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
🚀 Feature Proposal
Like
jest.resetModules()
, but only forgets whatever was initialized inside an explicit scope.Open to better naming.
Motivation
We often use
jest.resetModules()
in the React codebase to isolate individual tests.However, sometimes we also use
jest.resetModules()
for another purpose. We have some code that's shared between different packages, but ends up being bundled (i.e. copied) into all of them after the build time. But we run Jest on the source (building would've been too slow).As a result, with our setup there might be some accidentally shared state when running the tests that doesn't end up being shared in practice after the build. This can lead to weird bugs where tests tell us everything is okay, but it breaks in production. We've reduced this somewhat by running a subset of tests on compiled bundles, but this is still complicating some further work we need to do.
Usually we work around it like this:
This ensures
ReactDOM
andReactDOMServer
are properly isolated even if they happen to share some internal modules. The problem is that this wipes out all the modules, includingReact
. In some cases it matters for us thatReact
stays the same, but modules that were loaded when initializingReactDOM
orReactDOMServer
are discarded.Example
Pitch
I tried my best above. Maybe if there was a way to clear individual modules that would work for me although I need to clear all recursive dependencies that haven't already been loaded earlier.
The text was updated successfully, but these errors were encountered: