Test React element height with Jest

2020-04-07 03:23发布

问题:

I have a very simple React.js component that decorates a long block of markup with "Read more" / "Read less" functionality.

I have a few tests with Jest working, however, I am unable to assert that the DOM element height is increasing to the size of the original content.

In the Jest test environment my call to getDOMNode().scrollHeight does not appear to return anything.

Here is a link to the repository with the code and failing test: https://github.com/mguterl/react-jest-dom-question

Below is a simplified version of the code and test that illustrates the same issue:

Simplified Code

var ReadMore = React.createClass({
  getInitialState: function() {
    return {
      style: {
        height: '0px'
      }
    }
  },

  render: function() {
    return (
      <div>
        <div ref='content' className='read-more__content' style={this.state.style} dangerouslySetInnerHTML={{__html: this.props.content}} />
        <a onClick={this.expand} href='#'>Expand</a>
      </div>
    );
  },

  expand: function() {
    // This call to scrollHeight doesn't return anything when testing.
    var height = this.refs.content.getDOMNode().scrollHeight;

    this.setState({
      style: {
        height: height
      }
    });
  }
});

Test

jest.dontMock('../ReadMore');

global.React = require('react/addons');
var TestUtils = React.addons.TestUtils;
var ReadMore = require('../ReadMore');

describe('ReadMore', function() {
  var readMore;
  var content;
  var link;

  beforeEach(function() {
    readMore = TestUtils.renderIntoDocument(
      <ReadMore collapsedHeight='0px' content='<p>Hello World</p>' />
    );

    content = TestUtils.findRenderedDOMComponentWithClass(
      readMore, 'read-more__content');

    link = TestUtils.findRenderedDOMComponentWithTag(
      readMore, 'a');
  });

  it('starts off collapsed', function() {
    expect(content.getDOMNode().getAttribute('style')).toEqual('height:0px;');
  });

  it('expands the height to fit the content', function() {
    TestUtils.Simulate.click(link);
    expect(content.getDOMNode().getAttribute('style')).toEqual('height:100px;');
  });
});

回答1:

Jest "runs your tests with a fake DOM implementation (via jsdom) so that your tests can run on the command line" (http://facebook.github.io/jest/).

I would not expect something like the element height to be set, since it's not being run against a rendering engine to work out the height of any divs.

I would suggest setting a marker style class on the div in either state or both ("read-more" / "read-less"). Then your test can assert the presence or absence of a class.

Also - if you don't set the style attribute at all in "read more" mode, the enclosing div should be rendered to fully show the inner div (unless you're not just trying to show the whole inner div). So wouldn't it be adequate to test that the style attribute has the this.props.collapsedHeight value in "read less" mode, and is not set in "read more" mode?