-->

Testing Webpack built React components with Jest

2019-04-28 21:06发布

问题:

I have come across a problem where I need to run Jest tests on a React application that is being built by Webpack. The problem is handling the require of CSS files and images etc that Webpack would usually process with a loader. I need to know about what is the best approach to test my components correctly.

The React component:

import React from 'react';
// The CSS file is the problem as I want to actually test what it
// returns after webpack has built it.
import style from './boilerplate.css';

var Boilerplate = React.createClass({
    render: function() {
        return (
            <div>
                <h1 className={style.title}>react-boilerplate</h1>
                <p className={style.description}>
                    A React and Webpack boilerplate.
                </p>
            </div>
        );
    }
});

export default Boilerplate;

The Jest test:

jest.dontMock('./boilerplate.js');

var Boilerplate = require('./boilerplate.js');
var React = require('react/addons');
var TestUtils = React.addons.TestUtils;

describe('boilerplate', function() {

    var component;

    beforeEach(function() {
        component = TestUtils.renderIntoDocument(
            <Boilerplate />
        );
    });

    it('has a h1 title', function() {
        // I want to actually use 'findRenderedDOMComponentWithClass'
        // but cannot because I need to run the Webpack build to add a
        // CSS class to this element.
        var title = TestUtils.findRenderedDOMComponentWithTag(component, 'h1');
        expect(title.getDOMNode().textContent).toEqual('react-boilerplate');
    });

    it('has a paragraph with descriptive text', function() {
        var paragraph = TestUtils.findRenderedDOMComponentWithTag(component, 'p');
        expect(paragraph.getDOMNode().textContent).toEqual('A React and Webpack boilerplate.');
    });

});

I have come across this question which reassured me I was on the right lines having tried all these approaches myself but I have issues with all of the solutions I have come across:

Solution 1: Use a scriptPreprocessor file which strips out requires of non Javascript files that require a Webpack build e.g requiring .css, .less, .jpegs etc. This way we can tests the React component but nothing else.

Problem: I want to test some of the functionality that the Webpack build creates. E.g I use local, interoperable CSS and I want to test the Object of CSS classes returned from a require('whaterver.css') which Webpack creates. I also want to use findRenderedDOMComponentWithClass from React/TestUtils which means I need to build the CSS through Webpack.

Solution 2: Use scriptPreprocessor script which runs the component through Webpack and builds a test file (like jest-webpack does) and run tests on this output.

Problem: We can no longer use Jest's auto mocking as we would now be using Webpacks __webpack_require__(1). This is also slow to build every time you run a test file.

Solution 3: Much like solution 2 but run only one build for all test files before running npm test to solve the slow build time.

Problem: Same as Solution 2. No auto mocking.

Am I on the wrong path here or does anyone have any answers for this? Am I missing the obvious?

回答1:

I recently built Jestpack which integrates Jest with Webpack meaning you can use all of Webpack's features including CSS modules, file loading, code splitting, CommonJS / AMD / ES2015 imports etc. along with Jest's auto mocking.