3

I'm building an HoC to make it easy to create selectable table rows. I'm trying to write tests to ensure that it renders the wrapped component with the correctly passed through props. Unfortunately, I can't get my tests to work as it doesn't appear that enzyme is rendering all the components out (or, more likely, I'm doing something a bit silly).

HoC

import React, { PropTypes, Component } from "react";
import { omit } from "lodash/fp";

const propsFilter = omit(["onSelect"]);

export default function selectable(onSelect, isSelected) {
    return (component) => {
        const wrappedName = component.displayName || component.name || "Component";
        const displayName = `Selectable(${wrappedName})`;
        const onClick = () => onSelect && onSelect(!isSelected);

        class SelectableWrapper extends Component {
            render() {
                return <component onClick={ onClick } { ...propsFilter(this.props) } />;
            }
        }

        SelectableWrapper.displayName = displayName;
        SelectableWrapper.propTypes = Object.assign({
            onSelect: PropTypes.func,
            isSelected: PropTypes.bool,
        }, component.propTypes);

        return SelectableWrapper;
    };
}

Test

/* eslint-env mocha */

"use strict";

import React from "react";
import { expect } from "chai";
import { spy } from "sinon";

import { mount } from "enzyme";

import selectable from "../../../src/js/components/tables/selectable";

describe("<SelectableHOC />", () => {
    let onSelect, isSelected;

    const TestElement = () => <p className="test">Hi</p>;

    const el = () => selectable(onSelect, isSelected)(TestElement);
    beforeEach("setup spy", () => onSelect = new spy());

    it("renders the wrapped component, passing through props", () => {
        const hoc = el();
        const wrapper = mount(<hoc name="foo" />);
        expect(wrapper).to.contain("p.test");
    });

    it("doesn't pass through onSelect");
    it("sets onClick on the child component, which triggers onSelect");
});

When I try wrapper.debug() in the test, I just get <hoc data-reactroot="" name="foo"></hoc>.

The output of the test (which fails) is:

  1) <SelectableHOC /> renders the wrapped component, passing through props:
     AssertionError: expected <HTMLUnknownElement /> to contain p.test

     HTML:

     <hoc data-reactroot="" name="foo"></hoc>
      at Context.<anonymous> (test/components/tables/selectable.spec.js:43:39)
GTF
  • 8,031
  • 5
  • 36
  • 59
  • You should have capitalized your component name from `component ` to `Component`. Check this [question](https://stackoverflow.com/questions/30373343/reactjs-component-names-must-begin-with-capital-letters). In fact, rename it to something better, `Component` will clash with `React`'s `Component`. – Hardik Modha Jul 21 '17 at 04:27
  • Ah hah, that does seem to be it. I'd forgotten about React treating lowercase components as HTML tags. If you add that as a proper answer I'll mark it as the right one. – GTF Jul 21 '17 at 09:34
  • Added as an answer. :) – Hardik Modha Jul 21 '17 at 09:49

2 Answers2

1

The name of your component is in lowercase and in JSX name starting with a lowercase name are considered to be HTML tags, not the custom components. So you'll need to capitalize your component name.

Also, I recommend you changing the name of your component to something more meaningful to avoid clashing with the React.Component.

You can read more about it in the official react docs and this question.

GTF
  • 8,031
  • 5
  • 36
  • 59
Hardik Modha
  • 12,098
  • 3
  • 36
  • 40
0

You have to find the wrapped component and check the props on that

const elWrapper = wrapper.find('TestElement');
expect(elWrapper.prop('onClick').to.not.equal(null);
expect(elWrapper.prop('onSelect').to.equal(undefined);
ianhowe76
  • 161
  • 1
  • 4