Enzyme: Mount doesn't work with passed props in a stateless component

Created on 10 Nov 2018  路  3Comments  路  Source: enzymejs/enzyme

Current behavior

Hi, I spent some time trying to mount stateless component with passed props. It wasn't successfully, every time when I ran tests I got this error:

Error: Uncaught [Error: Warning: Invalid DOM property `%s`. Did you mean `%s`?%s]

   7 | console.error = message => {
>  8 |    throw new Error(message);
   9 | };

...
at mount (node_modules/enzyme/build/mount.js:21:10)
at Suite.<anonymous> (src/components/OrderedList/index.test.js:25:19)
at Object.describe (src/components/OrderedList/index.test.js:9:1)

Based on enzyme docs it should work. Also Without props it seems it works, shallow works properly as well.
Here is my simplified component _(OrderedList/index.js)_:

const OrderedList = ({title, items, type}) => {
  const orderedListItems = items.map((item) => {
    return (
      <li
        key={item.id}
        className="orderedlist__item">
        <div class="orderedlist__item-dash"></div>
        <a
          href={item.url}
          target="_blank"
          className="orderedlist__text"
        >{item.name}</a>
      </li>
    )
  });

  return (
    <div className="orderedlist">
      <h5 className="orderedlist__title font-s-12-secondary">{title}</h5>
      <ol className="orderedlist__list">
        {orderedListItems}
      </ol>
    </div>
  )
};

OrderedList.propTypes = {
  title: PropTypes.string,
  items: PropTypes.instanceOf(Array), // tried to replace with PropTypes.arrayOf(PropTypes.shape({})) it didn't work
  type: PropTypes.string
};

OrderedList.defaultProps = {
  title: '',
  items: [],
  type: ''
};

export default OrderedList;

and my test _(OrderedList/index.test.js)_:

import {shallow, render, mount} from 'enzyme';
import React from 'react';
import OrderedList from './index';

describe('<OrderedList />', () => {
  const title = 'title';
  const items = [
    {
      id: 1,
      text: 'test text 1',
      url: 'test.urlone'
    },
    {
      id: 2,
      text: 'test text 2',
      url: 'test.urltwo'
    }
  ];

  const component = mount(<OrderedList title={title} items={items} type=""/>);
  expect(component.find('li').first().childAt(1).is('a')).toBeTruthy();

it won't work as well, if I change two last lines like so:

const component = mount(<OrderedList/>);
component.setProps({...items}); // <- when I use two params like component.setProps({...title, ...items}) it doesn't show an error but also not change the DOM structure, so below test will fail
expect(component.find('li').first().childAt(1).is('a')).toBeTruthy();

and my _jestsetup.js_ file:

import { configure } from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';

configure({ adapter: new Adapter() });

console.error = message => {
   throw new Error(message);
};

The most interesting thing that I found was the case when I called several tests with the same component (see comments in the code), like so:

... <same variables as above> ...
describe('props tests', () => {
    beforeEach(() => {
      component = mount(<OrderedList />);
    });

   it('renders 1 simple link', () => {
      expect('items' in component.props()).toBeTruthy();  // test result: true
      expect(component.find('li').first().childAt(0).is('a')).toBeTruthy(); // test result: false
      component.unmount();
    });


    it('renders masked link', () => {
      component.setProps({...title, ...items});
      component.update();

      expect('items' in component.props()).toBeTruthy(); // test result: true
      component.unmount();
    });
 });

Expected behavior

Mount works with passed props like in docs: https://airbnb.io/enzyme/docs/api/ReactWrapper/mount.html

Your environment

macOS High Sierra v10.13.6
node v8.12.0
npm v6.4.1

API

  • [ ] shallow
  • [x] mount
  • [ ] render

Version

| library | version
| ------------------- | -------
| enzyme | ^3.7.0
| react | ^16.5.2
| react-dom | ^16.5.2
| react-test-renderer | ^16.5.2
| adapter (below) | ^1.6.0

Adapter

  • [x] enzyme-adapter-react-16
  • [ ] enzyme-adapter-react-16.3
  • [ ] enzyme-adapter-react-16.2
  • [ ] enzyme-adapter-react-16.1
  • [ ] enzyme-adapter-react-15
  • [ ] enzyme-adapter-react-15.4
  • [ ] enzyme-adapter-react-14
  • [ ] enzyme-adapter-react-13
  • [ ] enzyme-adapter-react-helper
  • [ ] others ( )

All 3 comments

I'm not sure why the error message is wrong, but you have this code:

<div class="orderedlist__item-dash"></div>

and that should be this:

<div className="orderedlist__item-dash" />

(className, not class)

Damn! Thanks, I haven't even noticed it, I thought it's probably related to the fact that it is a stateless component or something wrong with the configuration file.
I agree the error could have a bit better message and the stacktrace.

Since i think that error is coming from react itself (and your console.error shim is broken, because it鈥檚 not supporting printf-style formatting), i don鈥檛 think there鈥檚 anything actionable here.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ivanbtrujillo picture ivanbtrujillo  路  3Comments

abe903 picture abe903  路  3Comments

heikkimu picture heikkimu  路  3Comments

timhonders picture timhonders  路  3Comments

SandroMachado picture SandroMachado  路  3Comments