relay modern: how to mock relay for unit testing
Asked Answered
S

2

8

Am trying to test react relay modern container, but am having this issue.

TypeError: Cannot read property 'environment' of undefined

Here is the test code:

test('render component', () => {
  const tree = renderer.create(
    <User />,
  ).toJSON();

  expect(tree).toMatchSnapshot();
});
Swords answered 26/8, 2017 at 16:23 Comment(1)
You need to wrap your component in a RelayEnvironmentProvider and pass in a RelayMockEnvironment relay.dev/docs/guides/testing-relay-components/…Sade
L
-1

Add the below to __mocks__ folder. Then in the test add jest.mock('react-relay'); to the unit test that needs relay. This will mock out relay and leave just the component to test.

import React from 'react';
import PropTypes from 'prop-types';

const relayMock = jest.genMockFromModule('react-relay');

const relayChildContextTypes = {
  relay: PropTypes.object,
};

const relayEnvironment = {
  lookup: jest.fn(),
};

const relayContext = {
  relay: {
    environment: relayEnvironment,
    variables: {},
  },
};

const relayFragmentProps = {
  relay: {
    environment: relayEnvironment,
  },
};

const relayRefetchProps = {
  relay: {
    environment: relayEnvironment,
    refetch: jest.fn(),
  },
};

const relayPaginationProps = {
  relay: {
    environment: relayEnvironment,
    hasMore: jest.fn(),
    loadMore: jest.fn(),
    isLoading: jest.fn(),
  },
};

relayMock.__relayEnvironment = relayEnvironment;
relayMock.__relayFragmentProps = relayFragmentProps;
relayMock.__relayRefetchProps = relayRefetchProps;
relayMock.__relayPaginationProps = relayPaginationProps;

const makeRelayWrapper = (relayProps) => (
  (Comp) => {
    class HOC extends React.Component {
      getChildContext() {
        return relayContext;
      }

      render() {
        return <Comp {...this.props} {...relayProps}/>;
      }
    }

    HOC.childContextTypes = relayChildContextTypes;
    return HOC;
  }
);

relayMock.QueryRenderer = jest.fn(() => React.createElement('div', null, 'Test'));

relayMock.createFragmentContainer = makeRelayWrapper(relayFragmentProps);
relayMock.createRefetchContainer = makeRelayWrapper(relayRefetchProps);
relayMock.createPaginationContainer = makeRelayWrapper(relayPaginationProps);

module.exports = relayMock;
Libertinage answered 8/11, 2018 at 22:55 Comment(0)
U
-2

You actually dont need to mock the environment variable at all. What I usually do is add:

export class User

to the classdeclaration of the class that I want to test. (Make sure to keep the export default on your connected version of the same class).

I can then test the component the preferred way by importing the component without the need for relay like so in my test:

 import { User } from '../User'

This removes the need for mocking relay and you can pass in the props cleanly to the component.

Uncinate answered 18/1, 2018 at 7:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.