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
ESM test regression when run under quibble@0.6.10 #493
Comments
TL;DR: please revert that change, we'll need some other approach. In hindsight, the test here testdouble/quibble@5a83416#diff-be23e0c4db6635e4d0ad178cee88625670d2e51b6844c436f5b206c1fe5279bdR121 was flawed. The test lays out a reasonable desired property of the mocking library:
but there's also the equally desirable property that if an un-mocked module itself imports a mocked module, future imports of that module should use the mocked version. This requires reseting the module cache ... in direct conflict to the previous case.
My recent change to quibble broke this second property. Aside: Ideally, one could "hot-swap" existing static module references in other modules but... I don't think that is possible, given Module objects are read-only. Besides, if a static import is used in the root module scope, that code would not be refreshed as expected. But if it were possible that seems like an OK constraint to have on modules-under-test. The cache busting mechanism controlling this behavior is My initial thoughts are that this problem is truly cursed. My second thoughts are that perhaps proper mocking of ES modules is still possible, but only correctly when all calls to It could be enforced with an optional
This would basically "freeze" the module graph after every series of calls to |
Thanks @connorjclark! Tagging in @giltayar because he understands this better than I do. |
OK, having gone the whole route (implementing it my way, and then seeing that implementing it @connorjclark's way is simpler (although a few tweaks to the code are necessary), I think I understand the issues better now. Yes, we're in a "damned if we do, damned if we don't" situation here. BTW, this situation is not specific to ESM, and is relevant to any module loading/mocking situation. The question @connorjclark raised is this: if I mock a module B used by module A (which is unmocked), if I remock B and import A, should it make A load the newly mocked B, or stay with the original mock? If we go with the former, this means that A is reloaded and becomes A' (i.e. statics will change). If we go with the latter, the user is surprised that B is not mocked. From my point of view, the latter behavior, where the user is surprised that no mocking occurs even if mocking is requested, is more problematic than the latter. We should leave it at that! Yes, at the cost of module state being difference between imports. Your "strict" mode is an interesting idea that helps debug module-state-being-unequal.issues, but my guess is that most users won't care if there is reloading of modules and so won't need the "strict" mode. And if they do care, I'm not sure that they would know to turn it on and make it help them figure out what the problem is! First off, whatever the result we decide, there's needs to be a test for that, so that we will document this behavior :-) @searls what do you think? There are two behaviors, each having their own pros and cons: The scenario is this: A is a module that imports B Now the code: import {func} from A
Obviously, this sounds like an obvious choice (1), but lets modify this scenario a bit: import {func} from A In this case, we're mocking a module that has no connection to A, yet A is still reloaded. Which is weird. Now option 2 makes more sense because in this case module variables stay the same because now func and func2 are the same. |
I agree with this. It's very likely/common that a test suite will contain numerous different mockings of a same dependency.
I also agree with this. It seems like solving this with ✨ magic ✨ to figure out if a re-import is desirable is going to be fraught and surprising to just about anyone, and a I'm about to leave for a weekend so I'm going to revert testdouble/quibble#72 (review) but if either of you want to try introducing such a mode to quibble (and maybe a mirror property to Thank you both for taking the time to explain what's going on so clearly! |
Tagging in @connorjclark if he'd be willing to look at these test failures:
After updating to quibble@0.6.10 (this PR testdouble/quibble#72 ),
npm run test:esm
is failing in testdouble.js:The text was updated successfully, but these errors were encountered: