Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How Can I Manually Mock Svg's in my Tests?

I'm using a stub file to mock images in my application, which works 99% of the time for me. However, I have a component that will render different images based on input, so I want to be able to check in my unit tests that the input creates the correct output.

Basically what I'm looking to do is if the user inputs "Lion", my component will display a picture of a lion, "Tiger a tiger, etc. Using moduleNameMapper, it's always test-file-stub and I want to be able to jest.mock('../lion.svg', ()=> 'lion.svg') for specific tests.

like image 692
Yatrix Avatar asked Mar 14 '19 18:03

Yatrix


People also ask

How do you mock native modules jest?

Mocking native modules​Make sure that the path to the file in setupFiles is correct. Jest will run these files before running your tests, so it's the best place to put your global mocks. If you're not using Jest, then you'll need to mock these modules according to the test framework you are using.

How do you mock an import in jest?

To mock an imported function with Jest we use the jest. mock() function. jest. mock() is called with one required argument - the import path of the module we're mocking.


2 Answers

Thanks to Jest's transform config setting you may do that.

package.json

"jest": {
  "transform": {
    "\\.svg$": "<rootDir>/fileTransformer.js"
  }
  ...
}

IMPORTANT

You need to explicitly provide transform to other extensions (especially *.js and *.jsx) otherwise you will get errors. So it should be something like:

"transform": {
  "^.+\\.js$": "babel-jest",
  "\\.svg$": "<rootDir>/fileTransformer.js"
   ...
}

As for fileTransformer.js it just emulates exporting file's path(you may add any transformation to strip the path or extension or whatever):

const path = require('path');

module.exports = {
  process(src, filename) {
    return `module.exports = ${JSON.stringify(path.basename(filename))};`;
  }
};

It means

import svgIcon from './moon.svg';

will work just like

const svgIcon = 'moon.svg'

So for component containing

...
  <img src={svgIcon} />

you may write assertion like

expect(imgElementYouMayFind.props.src)
  .toEqual('moon.svg')
like image 145
skyboyer Avatar answered Sep 28 '22 08:09

skyboyer


Just a small addition to what @skyboyer suggest:

module.exports = {
  process(src, filename) {
    return `module.exports = ${JSON.stringify(path.basename(filename))}`;
  }
};

instead you need have it like that:

module.exports = {
  process(filename) {
    return `module.exports =  ${JSON.stringify(path.basename(filename))};`;
  }
};

pay attention to ; after closing curly bracket.

like image 38
Pavel Ivanov Avatar answered Sep 28 '22 07:09

Pavel Ivanov