0

Here is the functional component some-table.jsx I am testing:

import React from 'react';

const SomeTable = ({ somethings }) => (
  <>
    {somethings.map(something => {
      return <SomeRow key={something} something={something} />
    })}
  </>
);

export const SomeRow = ({ something }) => {
  return <p>{something}</p>
}

export default SomeTable;

Here is my test file:

import { create } from "react-test-renderer";
import SomeTable, { SomeRow } from "../common/ui/some-table";

test("check SomeTable has row", () => {
  const renderer = create(<SomeTable somethings={["Hello", "World"]} />);
  const allRows = renderer.root.findAllByType(SomeRow);
  expect(allRows.length).toBe(2);
});

This test passes. However if I move SomeRow into its own file it then fails:

some-table.jsx:

import React from 'react';
import { SomeRow } from './some-row';

const SomeTable = ({ somethings }) => (
  <>
    {somethings.map(something => {
      return <SomeRow key={something} something={something} />
    })}
  </>
);

export default SomeTable;

some-row.jsx:

import React from 'react';

export const SomeRow = ({ something }) => {
  return <p>{something}</p>
}

failure:

expect(received).toBe(expected) // Object.is equality

Expected: 2
Received: 0

Any ideas why this might be please? Thank you for reading.

Joseph Beuys' Mum
  • 2,395
  • 2
  • 24
  • 50

1 Answers1

1

In the real-world scenario that these Some... test files were created to solve, the problem was caused by React's memo() function:

import React, { memo } from 'react';
...
export default memo(SomeRow);

One workaround for which is the following:

const allRows = renderer.root.findAllByType(SomeRow.type);

Props to bensampaio for that tip. You'll find a bunch of other discussion on that link too that you might find helpful, including:

Pin react, react-dom, react-test-renderer to 16.11.0, and most importantly add a dependency to react-is@16.11.0, or use a predicate like the following:

const elementByType = (type) => (element) => (
    element.type === type // Match non-memo'd
    || element.type === type.type // Match memo'd
);

It should also be noted that I did something silly too. The imports were wrong. This:

import SomeTable, { SomeRow } from "../common/ui/some-table";

Should have been this:

import SomeTable from "../common/ui/some-table";
import { SomeRow } from "../common/ui/some-row";
Joseph Beuys' Mum
  • 2,395
  • 2
  • 24
  • 50