9

Is it possible to use react-virtualized and enzyme together? When I try to use them together I seem to get an empty list of items in the grid.

camwest
  • 323
  • 1
  • 3
  • 6

3 Answers3

5

The 2 should work together, yes. I believe the likely problem is that the react-virtualized component is being given a width or height of 0 which causes it not to render anything. (It only renders enough to fill the "window" it has.)

Assuming you're using the AutoSizer HOC- (most people do)- then one pattern I've found helpful is to export 2 versions of components- one that expects explicit width/height properties and one that wraps the other with an AutoSizer. Pseudo code would be:

import { AutoSizer, VirtualScroll } from 'react-virtualized'

// Use this component for testing purposes so you can explicitly set width/height
export function MyComponent ({
  height,
  width,
  ...otherProps
}) {
  return (
    <VirtualScroll
      height={height}
      width={width}
      {...otherProps}
    />
  )
}

// Use this component in your browser where auto-sizing behavior is desired
export default function MyAutoSizedComponent (props) {
  return (
    <AutoSizer>
      ({ height, width }) => (
        <MyComponent
          height={height}
          width={width}
          {...props}
        />
      )
    </AutoSizer>
  )
}
bvaughn
  • 12,062
  • 37
  • 43
  • One thing I forgot to mention. I'm using enzyme in node.js using jsdom. Does AutoSizer rely on the real DOM measurement apis? – camwest Jun 15 '16 at 03:37
  • It depends on `getBoundingClientRect` and `getComputedStyle`. You can see how it measures things here: https://github.com/bvaughn/react-virtualized/blob/master/source/AutoSizer/AutoSizer.js#L93 – bvaughn Jun 15 '16 at 14:46
  • 1
    Ok great then your recommendation of bypassing AutoResizer is the best one since getBoundingClientRect isn't accurate in jsdom. – camwest Jun 16 '16 at 23:08
  • Shouldn't you pass `height` and `width` (the parameters of AutoSizer render callback) to MyComponent? – Alfonso Pérez Nov 15 '17 at 19:45
  • Yeah. Example was just written quickly as a sketch. I updated it. – bvaughn Nov 16 '17 at 16:29
  • 1
    You are a life saver! <3 – Anders Ekman Jan 16 '19 at 12:27
4

as of react-virtualized 9.12.0 the Autosizer has defaultWidth and defaultHeight properties. I found setting those meant enzyme tests ran correctly - rendering the child rows as expected.

<AutoSizer disableHeight defaultWidth={100}>
    {({ width }) => (
  ....
  )}
</AutoSizer>
Rob Clayburn
  • 256
  • 1
  • 3
  • Thanks so much! I couldn't figure out why `console.log(wrapper.debug());` wasn't showing any data for rows - only the headers were being shown. – Shiraz Aug 08 '20 at 22:24
2

Putting this in my test case worked for me:

import { AutoSizer } from 'react-virtualized';

// ...

it('should do something', function() {
    spyOn(AutoSizer.prototype, 'render').and.callFake(function render() {
        return (
            <div ref={this._setRef}>
                {this.props.children({ width: 200, height: 100 })}
            </div>
        );
    });

    // do something...

I use Jasmine's spyOn here, but other libraries have their own ways of overwriting functions. Keep in mind that this is pretty fragile against future changes to the react-virtualized library (this._setRef was just yanked from the source code), and may give you false positives.

Chris
  • 1,636
  • 20
  • 34
  • Did this with jest like this: `jest.mock('react-virtualized-auto-sizer', () => { return mockAutoSizer; });` where mockAutoSizer is the function you just described. – NotSimon Jul 22 '20 at 22:20