Using CSS modules in react when testing with enzyme

Apr 24, 2021·
Gert de Pagter
Gert de Pagter
· 2 min read

We’ve been using CSS modules in a react project, and wanted to use those classes in our tests. However we quickly ran into the problem that none of the classes were found. Any wrapper.exists would be false. The problem was with our css modules, as they were not imported correctly during tests.

Our code looked like this:

import styles from './QA.scss?module';

interface QAProps {
  question: string;
  answer?: string;
  isOpen?: boolean;
}

const QA:React.FC<QAProps> = ({question, answer, isOpen}) => (
  <div>
  <p>{question}</p>
  {isOpen && <div className={styles.Answer}>{answer}</div>}
  </div>
);

When testing it we tried the following:

it('has no answer when not opened', () => {
  const wrapper = shallow(<QA question="hi" />)
  // passes
  expect(wrapper.exists('.Answer')).toBe(false);
});

it('has an answer when opened', () => {
  const wrapper = shallow(<QA question="hi" answer="answer" isOpen />)
  // fails
  expect(wrapper.exists('.Answer')).toBe(true);
});

The problem lied in our fileMock for jest.

  // jest.config.js
  "moduleNameMapper": {
    "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/__mocks__/fileMock.js",
    "\\.(scss|less|scss\\?module)$": "<rootDir>/__mocks__/fileMock.js"
  },
// __mocks__/fileMock.js
module.exports = 'content';

Because of this export, styles.Answer would be undefined. Instead, during our tests we want it to just return the name of the property. In PHP you would use the __get magic method. (Un)fortunately, this is also possible in js, through a Proxy object.

We make a proxy of an empty object, that always returns the property that is being requested. And in the jest.config.js we update the css files to refer to this new cssMock.js file.

// __mocks__/cssMock.js
const target = {};

const handler = {
    get: function(target, prop) {
        return prop;
    }
};

const proxy = new Proxy(target, handler);

export default proxy;

Now, our tests pass, and our css modules can be used within our tests.

Gert de Pagter
Authors
Software Engineer
My interests include software development and math.