-
-
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
Allow mocking require.resolve
#9543
Comments
Oooh, I like it! It would essentially be Not a huge fan of needing to replicate all of |
Somehow I didn't realize that my proposal could be directly related to Do you think that |
Oh, I didn't know about If no one from the team has concerns with this feature request, I could start working on an implementation next week. |
I think virtual mocks should cover your use case. Let's try that first before adding more APIs to Jest. I do not think that mocking |
Since Babel internally directly calls |
You should be able to create virtual mocks to ensure that You can also require the module after calling |
It doesn't seem to work: describe.only("virtual mocks", function() {
it("finds preset", () => {
try {
const preset = () => ({});
// also tested with "../../../node_modules/babel-preset-test-1234"
jest.doMock("babel-preset-test-1234", () => preset, { virtual: true });
expect(() =>
babel.transformSync("code;", {
presets: ["babel-preset-test-1234"],
configFile: false,
}),
).not.toThrow();
} finally {
jest.dontMock("babel-preset-test-1234");
}
});
}); reports
It doesn't work because the jest replacement for Also, I don't know what |
Thanks for trying it out and checking. That's a good observation that I missed. Now the question is: should |
If I still think that explicitly specifying to Jest what to return when jest.mock("foo", () => {}, { virtual: true, resolve: "/tmp/node_modules/foo" }); Also, I realized that my original proposal doesn't cover a use case we would need in half of our resolution-related tests: checking that the correct error message is thrown when It probably would need a separate option, which makes a mock throw whenever jest.mock("foo", () => {}, { virtual: true, missing: true }); |
I'm a bit hesitant of adding new APIs to Jest because you are running into a very limited use case that not many people are encountering. I think I would prefer simply making it so you can overwrite require.resolve, then you can do whatever you like with it. |
What I like about expanding jests API is that you can have reusable mocks (possibly distributed through npm) without |
I agree with this sentiment. However, I don't think that mine is a limited use case:
However, I didn't find anyone else asking how to mark a mocked module as not existing. Let's keep the discussion focused only on the original proposal.
This is something I personally don't need, but I definitely see how it would be useful for the rest of the community!
💯 The |
I'm down with adding a One challenge with overloading is that |
Sure, I will prepare a draft PR in the next days! |
Hey, sorry all for the super long time without any response. I tried implementing it (I wanted to implement both the proposals, to check which one was better), but didn't manage to figure out how the If anyone wants to implement it it would be highly appreciated, but I can still work on updating the Babel plugin if needed. |
Hey guys ! Having that in mind, here is, basically, what I've done:
const glob = require('glob');
let mapping = {};
// Looks for "module-resolution.json" files in all the `__tests__` directories
glob
.sync(`${__dirname}/../../packages/**/src/**/__tests__/modules-resolution.json`)
.forEach((file) => {
// For each of them, merges them in the "mapping" object
mapping = { ...mapping, ...require(file) };
});
function resolver(path, options) {
// If the path corresponds to a key in the mapping object, returns the fakely resolved path
// otherwise it calls the Jest's default resolver
return mapping[path] || options.defaultResolver(path, options);
}
module.exports = resolver;
module.exports = {
roots: ['<rootDir>'],
testMatch: ['<rootDir>/packages/**/__tests__/**/*.test.js'],
collectCoverageFrom: ['packages/**/src/**/*.js', '!packages/**/src/__tests__/**'],
resolver: '<rootDir>/test-utils/resolver',
};
{
"fake-module": "/path/to/fake-module"
} This do the job for me so far and I think that, starting from this example, we could do something more complex but more developer friendly ! |
@cpojer I think any project that has optional peer dependencies and alters its behaviours based on the existence of those dependencies likely cannot implement full test coverage because |
Would love to have this functionality too! My usecase specifically is checking if a directory exists for example |
The feature has been accepted, so no need to try to convince us 🙂 PR very much welcome! |
Hey @SimenB I read
Am I to understand that |
Correct, that's part of what this issue is about. |
This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 30 days. |
This limitation still exists in Jest where it's not possible to mock |
I'm trying to use |
I found relative problem with @fastify/swagger-ui. This library is using "require.resolve('./static/logo.svg')" and as result test broken with moduleNameMapper configuration |
🚀 Feature Proposal
The
require.resolve
function is re-created for every file: this is needed so that it starts resolving from the correct location.However, this makes it impossible to mock it:
require.resolve = jest.fn()
doesn't work.I propose adding an API similar to
jest.mock
specifically forrequire.resolve
's behavior.Motivation
We have different tests in
@babel/core
that test plugins/presets aliasing (ref). For example, we test that when someone uses@babel/env
in their config Babel tries to resolve@babel/preset-env
.We currently rely on "fake"
node_modules
folders, however:Example
Maybe something like this?
Pitch
Mocks are already handled by the Jest core platform 😁
The text was updated successfully, but these errors were encountered: