Replies: 3 comments 7 replies
-
Can't you do this without a plugin? Some edge cases that don't work? From what I know, an ES module is a global singleton, so if you import it via a normal static import syntax like |
Beta Was this translation helpful? Give feedback.
-
This is the way to go. It will make code highly-standard and increase its longevity. Anything else reduces simplicity of test-runner, will be more maintenance work, and could mean breaking changes and breakages down the road, and more difficult to port to other systems later.
What issues did you have with import maps? Have you already tried The only difference is that for some test, the interception is not located in the test file, but in the test-runner config, which is not too big of a deal at the end of the day. You can comment in the test file like so: import foo from 'foo' // mocked in test-runner import map
import bar from 'bar' // mocked in test-runner import map
import baz from 'baz' then you know where to look. Then you don't need top-level Basically it seems that adding the complexity is not worth just to define the module mock inside the test file. |
Beta Was this translation helpful? Give feedback.
-
As people seem generally positive on this proposal, I will continue by creating a full-fletged PR (tests, docs, examples,, ..) where the plugin is delivered in a sub project for the web monorepo. Thanks already for the comments! |
Beta Was this translation helpful? Give feedback.
-
Hi there! 👋
Problem statement
I've been creating tests in JavaScript for quite some time. A practice I see coming up every so often, especially when creating unit tests, is hooking into dependencies and overriding the default behaviour of used functions. When these dependencies are being accessed from the global window object, it is pretty easy to override the behaviour of functions (eg.
window.fetch()
)Nowadays, however, we live in an ES modules world, where dependencies are brought in using an
import
of the module. When creating tests for such systems it is not always easy to override the behaviour of imported modules, as normal exported functions are not allowed to be overridden. There have been a number of solutions until now:These types of solutions clutter your code, and are not always easy to create, especially when the system under test is a class or a component.
Although import maps deliver the ability to intercept modules, their usage within tests is not really straightforward. Also, overriding behaviour multiple times, requires a more elaborate setup.
Proposal
With
@web/test-runner
and@web/dev-server
, we embrace the usage of ES modules and other standard practices. But we also get a powerful system to customize the experience.This allows us to create a plugin that enables us to actually intercept import calls, and change module exports when running tests in
@web/test-runner
: https://github.com/tmsns/web/tree/intercept/packages/test-runner-interceptHere is a sample of the proposed usage of the plugin. The idea is to keep its usage as simple and straightforward as possible (note: I've already been doing some back-and-forth on this with @LarsDenBakker)
Setup:
Simple test scenario:
More extended test scenario with common helper libraries:
As this functionality is so useful when creating tests with ES modules, the hope is that this plugin could be an official plugin of the @web monorepo and maybe even bundled in
@web/test-runner
. 🙈What does the community think?
@web/test-runner
?The repo with the plugin is a barebones project, but the code does actually work. So, if you already have some questions or remarks on the implementation, feel free to share this as well. Of course, if we go further with this, we'll need to add tests, document it, and convert it to TS. But for now, I kept it lightweight.
Beta Was this translation helpful? Give feedback.
All reactions