Skip to content
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

Compatibility of version 4.0 and jest #97

Closed
pcorpet opened this issue Oct 31, 2023 · 6 comments
Closed

Compatibility of version 4.0 and jest #97

pcorpet opened this issue Oct 31, 2023 · 6 comments

Comments

@pcorpet
Copy link

pcorpet commented Oct 31, 2023

I use jest for my test and it's choking on the new syntax introduced in 4.0 (Resource Queries). Jest themselves are planning on supporting it but the PR is not moving and it has been a while.

Do you have an idea on how I could make the upgrade to v4 and keep my jest tests? Maybe there's a way to make the resource query syntax optional?

@pcorpet pcorpet changed the title Compatbility of version 4.0 and jest Compatibility of version 4.0 and jest Oct 31, 2023
@denchen
Copy link

denchen commented Nov 13, 2023

So I was able to find a workaround with a combination of two things:

  1. Install babel-plugin-import-remove-resource-query and add the plugin to your Jest babel config
  2. In your test, mock out the SVG:
    jest.mock('/path/to/your/image.svg', () => () => <div className="mock-svg" />);

@pcorpet
Copy link
Author

pcorpet commented Nov 13, 2023

Thanks I've made it worked. Note that I've used a generic transform in my jest config so that I didn't need to mock each svg.

The solution that worked for me:

  1. Install babel-plugin-import-remove-resource-query and add the plugin to your Jest babel config (thank you @denchen !)
  2. Update my jest.config.js file with a:
transform: {
  '^.+\\.svg$': `<rootDir>/jest/__mocks__/svg.js`,
}
  1. and then the content of this svg.js file:
module.exports = {
	process() {
		return {
			code: 'module.exports = () => null;',
		}
	},
	getCacheKey() {
		// The output is always the same.
		return 'svgTransformSvgr4'
	},
}

@pcorpet pcorpet closed this as completed Nov 13, 2023
@denchen
Copy link

denchen commented Nov 13, 2023

@pcorpet Your solution is much nicer. I did have a bit of a hiccup where my tests were still failing with trying to load the SVG, but it was due to a caching problem. I ran Jest once with --no-cache, and it fixed the issue.

@mmirus
Copy link

mmirus commented Nov 28, 2023

After some trial and error, I went about making v4 work with jest in a different way that seems to be working.

In jest.config.ts:

import type { Config } from '@jest/types';

const config: Config.InitialOptions = {
  // ...
  moduleNameMapper: {
    // ...
    '^(.+\\.svg)\\?react$': '<rootDir>/src/__mocks__/svg.tsx',
  },
  // ...
};

module.exports = config;

In src/__mocks__/svg.tsx:

import React from 'react';

const SvgrMock = React.forwardRef<HTMLSpanElement>((props, ref) => (
  <span ref={ref} {...props} />
));
SvgrMock.displayName = 'SvgrMock';

export const ReactComponent = SvgrMock;
export default SvgrMock;

@josegoval
Copy link

After some trial and error, I went about making v4 work with jest in a different way that seems to be working.

In jest.config.ts:

import type { Config } from '@jest/types';

const config: Config.InitialOptions = {
  // ...
  moduleNameMapper: {
    // ...
    '^(.+\\.svg)\\?react$': '<rootDir>/src/__mocks__/svg.tsx',
  },
  // ...
};

module.exports = config;

In src/__mocks__/svg.tsx:

import React from 'react';

const SvgrMock = React.forwardRef<HTMLSpanElement>((props, ref) => (
  <span ref={ref} {...props} />
));
SvgrMock.displayName = 'SvgrMock';

export const ReactComponent = SvgrMock;
export default SvgrMock;

I had to add also "^(.+\\.svg)$": "<rootDir>/src/__mocks__/svg.tsx",. Here is my moduleNameMapper:

"moduleNameMapper": {
      "^(.+\\.svg)\\?react$": "<rootDir>/src/__mocks__/svg.tsx",
      "^(.+\\.svg)$": "<rootDir>/src/__mocks__/svg.tsx",
}

@jarosik10
Copy link

I've come up with some other idea.

  1. Add moduleNameMapper to help jest with handling this import syntax: .svg?react. It converts imports like ./icons/myIcon.svg?react to ./icons.myIcons.svg
  moduleNameMapper: {
    '^(.*).svg\\?react$': '$1.svg',
  }
  1. Add trasformer jest-transformer-svg . '^.+\\.svg(\\?react)?$' - it uses 'jest-transformer-svg' for normal .svg imports and also .svg?react.
  transform: {
    '^.+\\.svg(\\?react)?$': 'jest-transformer-svg',
  },

With this setup svgs are rendered like this:

<svg
   class="opt-icon icon iconSmall moreIcon"
   data-file-name="SvgMore_vert24px"
/>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants