简体   繁体   中英

Enzyme's shallow is rendering children's children?

I'm trying to set up some simple testing in Jest and Enzyme for my React App. I'm using shallow to render the main container for my app , however it appears that the children and all of the children below are being rendered.

  ● Test suite failed to run

    TypeError: Cannot read property 'NaN' of undefined

       7 | export function getRandomColor() {
       8 |      console.log(colors);
    >  9 |      return colorsKeys[Math.floor(Math.random() * colorsLength)];
         |                       ^
      10 | }
      11 |
      12 | export function determineColor(genotype) {

      at getRandomColor (src/utils/determineColor.js:9:19)
      at Object.<anonymous> (src/exampleState.js:10:16)
      at Object.<anonymous> (src/reducers/flowersReducer.js:1:1)
      at Object.<anonymous> (src/reducers/indexReducer.js:2:1)
      at Object.<anonymous> (src/index.js:14:1)
      at Object.<anonymous> (src/utils/determineColor.js:5:1)
      at Object.<anonymous> (src/components/NewFlowerFromPunnettButton.js:4:1)
      at Object.<anonymous> (src/components/Dashboard.js:2:1)
      at Object.<anonymous> (src/App.jsx:6:1)
      at Object.<anonymous> (test/App.test.js:4:1)

Per the Enzyme docs "Shallow rendering is useful to constrain yourself to testing a component as a unit, and to ensure that your tests aren't indirectly asserting on behavior of child components."

This SO answer seems to clarify that shallow "will render all its childs and childs of the childs and so on."


    //App.test.js
    import React from "react";
    // shallow prevents rendering of sub components????
    import { shallow, mount, render } from "enzyme";
    import App from "../src/App";

    describe("<App />", () => {
        const app = shallow(<App />);
        it("Should render ", () => {
            expect(app).toMatchSnapShot();
        });
        it("Should have <Punnett/> <Dashboard/> and <FlowerTable />", () => {
            expect(app.find("<Punnett />")).toBeTruthy();
            expect(app.find("<Dashboard/>")).toBeTruthy();
            expect(app.find("<FlowerTable />")).toBeTruthy();
        });

    });


    //App.jsx
    import React, { Component, Fragment } from "react";

    import "./css/App.css";
    import Punnett from "./components/Punnett";
    import FlowerTable from "./components/FlowerTable/FlowerTable";
    import Dashboard from "./components/Dashboard";

    class App extends Component {
        render() {
            return (
                <Fragment>
                    <div className="App">
                        <Punnett />
                        <Dashboard />
                    </div>
                    <div className="App">
                        <FlowerTable display={true} />
                    </div>
                </Fragment>
            );
        }
    }

    export default App;


    // determineColor.js
    import { colors } from "../types/colors";
    const colorsKeys = Object.keys(colors);
    const colorsLength = colorsKeys.length;

    import { store } from "../index";

    export function getRandomColor() {
        console.log(colors);
        return colorsKeys[Math.floor(Math.random() * colorsLength)];
    }

I'm expecting that either shallow does not render the children, or if the intended behavior is to render all children, that the children be able to import their modules correctly. Swapping shallow for render results in the same error.

Reproducible by cloning and running npm run test on https://github.com/nodes777/flower-game-phaser3

shallow does render children only, you are correct. root cause: seems "./components/Dashboard"; has code inside that runs on import - some top level code that is execution not declaration.

You may either change Dashboard not doing that, or provide data it needs to work, or mock it explicitly in every single test that may import it directly or indirectly:

App.test.js:

jest.mock('./components/Dashboard');

if you choose later approach you may consider automocking by creating components/Dashboard/__mocks__/index.jsx (or how is name of file with Dashboard) but beware of bug in jest that disallow you from using automock for more than one index.js regardless they are in different folders

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM