Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jest, enzyme - testing a method that returns jsx

I have the following component:

import React, { Component } from 'react';
import {Link, IndexLink} from 'react-router';

class Navbar extends Component {

  renderLinks = (linksData) => {
    return linksData.map((linkData) => {
      if(linkData.to === '/') {
        return(
          <div className="navbar-link-container" key={linkData.to}>
            <IndexLink activeClassName="navbar-active-link" to={linkData.to}>
              <i className="navbar-icon material-icons">{linkData.icon}</i>
              <span className="navbar-link-text">{linkData.text}</span>
            </IndexLink>
          </div>
        )
      }
      else {
        return(
          <div className="navbar-link-container" key={linkData.to}>
            <Link activeClassName="navbar-active-link" to={linkData.to}>
              <i className="navbar-icon material-icons">{linkData.icon}</i>
              <span className="navbar-link-text">{linkData.text}</span>
            </Link>
          </div>
        )
      }
    })
  };

  render() {
    return (
      <div className={`navbar navbar-${this.props.linksData.length}`}>
        {this.renderLinks(this.props.linksData)}
      </div>
    )
  }
}

Navbar.propTypes = {
  linksData: React.PropTypes.array.isRequired,
};

export default Navbar;

Now I am trying to write a unit test that will check the if condition (returning IndexLink or Link depending on the .to property):

But I can't seem to test for the exact jsx return of the function, since when I console.log one of the returns I get this:

{ '$$typeof': Symbol(react.element), type: 'div', key: '/', ref: null, props: { className: 'navbar-link-container', children: { '$$typeof': Symbol(react.element), type: [Object], key: null, ref: null, props: [Object], _owner: null, _store: {} } }, _owner: null, _store: {} }

This is the test I have written so far:

it('renderLinks should return a IndexLink', () => {
    const wrapper = shallow(<Navbar linksData={mockLinksData}/>);
    const renderLinksReturn = wrapper.instance().renderLinks(mockLinksData);
    let foundIndexLink = false;
    renderLinksReturn.map((linkHtml) => {
      console.log(linkHtml);
    });
    expect(foundIndexLink).toBe(true);
  })

Now I do not know what to test against to see if the function is running correctly. Is there a way to 'mount' the return of the function like a component? Or is there a simple method to return a html string of the actual return that I can check against?

like image 401
Miha Šušteršič Avatar asked Mar 16 '17 14:03

Miha Šušteršič


People also ask

Can a function return JSX in React?

JSX stands for JavaScript XML, a coding standard that allows you to use JavaScript expressions and other HTML features inline. Using JSX, you can create a function and return a set of JSX elements to a variable, and that variable used is to render the elements inside the render() function in React.

How would you test the React components using Jest and enzymes?

Both Jest and Enzyme are meant to test the react applications. Jest can be used with any other Javascript framework, but Enzyme is meant to run on react only. Jest can be used without Enzyme, and snapshots can be created and tested perfectly fine. But the Enzyme adds additional functionality to it.

What is the use of Enzyme in Jest?

Jest and Enzyme are tools which are used in tandem to test React components, and are used in the C#Bot testing framework for unit tests of client-side components. While they are used in this context to test react components, Jest is not specific to React, and can be used in other JavaScript applications.


2 Answers

To build on top of @Nachiketha 's answer, that syntax won't work when what's returned is a fragment, this can be solved by wrapping the result in a div like:

const renderLinks = shallow(<div>
    {wrapper.instance().renderLinks(mockLinksData)
    </div>
)}

as suggested in this tread.

like image 185
randomguy04 Avatar answered Oct 19 '22 03:10

randomguy04


Faced similar issue where we were passing a jsx component to another component as a prop.

You can shallow render the returned jsx since it's like a valid React Function/Stateless Component. eg:

const renderLinks = shallow(wrapper.instance().renderLinks(mockLinksData))

And continue with your usual enzyme assertions.

like image 20
Nachiketha Avatar answered Oct 19 '22 05:10

Nachiketha