'Jest unable to recognize SVG component

Jest is raising this error on one of my components:

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: number.

Check the render method of DoubleTappedClapAnim. at fn (C:\Users\fasta\ExhibitU\components\screen_specific\feed\FeedItem_components\DoubleTappedClapAnim.tsx:11:24)

at printWarning (node_modules/react/cjs/react.development.js:220:30)

at error (node_modules/react/cjs/react.development.js:196:5)

at Object.createElementWithValidation [as createElement] (node_modules/react/cjs/react.development.js:2215:7)

at Component (components/screen_specific/feed/FeedItem_components/DoubleTappedClapAnim.tsx:26:9)

at renderWithHooks (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:6016:18)

at mountIndeterminateComponent (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:8744:13

at beginWork$1 (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:9966:16)

at performUnitOfWork (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13800:12)

I understand that this error is commonly solved by fixing imports.

However the component which I'm running Jest on is importing an SVG (.svg extension picture), which I've only seen one way of importing correctly (& dynamically).

Here's that DoubleTappedClapAnim.tsx component:

import React from "react";
import { Animated, StyleSheet } from "react-native";
import Cheerfill from "../../../../assets/Icons/clap-fill.svg";
import Cheer from "../../../../assets/Icons/clap.svg";

const DoubleTappedClapAnim = (props) => {
  return (
    <Animated.View
      style={{
        ...styles.container,
        opacity: props.fadeAnim,
        transform: [{ translateY: props.slideAnim }],
      }}
    >
      {props.clap ? (
        <Cheerfill
          style={{
            marginTop: props.height,
            ...props.clapContainer,
          }}
          height={props.height / 5}
          width={props.width / 5}
          fill={props.darkModeValue ? "white" : "black"}
        />
      ) : (
        <Cheer
          style={{
            marginTop: props.height,
            ...props.clapContainer,
            transform: [{ rotate: "5deg" }],
          }}
          height={props.height / 5}
          width={props.width / 5}
          fill={props.darkModeValue ? "white" : "black"}
        />
      )}
    </Animated.View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: "center",
    alignItems: "center",
  },
});

export default DoubleTappedClapAnim;

and this is my DoubleTappedClapAnim.test.js:

import React from "react";
import renderer from "react-test-renderer";
import DoubleTappedClapAnim from "../DoubleTappedClapAnim";

test("matches previous snapshot and renders correctly", () => {
  const tree = renderer.create(<DoubleTappedClapAnim />).toJSON();
  expect(tree).toMatchSnapshot();
});

I'm wondering if anyone has a possible solution or workaround for this?

I've done the typical "transformIgnorePatterns" route, but I think that only goes so far for solving this problem.



Solution 1:[1]

You can get around this by mocking your svg assets, so a string is returned rather than the svg.

jest.mock("../../../../assets/Icons/clap-fill.svg", () => 'Cheerfill'))
jest.mock("../../../../assets/Icons/clap-fill.svg", () => 'Cheer'))

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Laurence James