简体   繁体   中英

Testing a child component's conditional rendering in React Jest/Enzyme

I am trying to add more tests for this file:

import React, { useContext } from 'react';
import UserContext from '../../contexts/user';
import styles from './index-styles.scss';

const UserLogo = ({ isMember }) =>
  isMember ? (
    <div className={styles.memberLogo}>&nbsp;</div>
  ) : (
    <div className={styles.logo}>&nbsp;</div>
  );

const UserDesc = ({ isMember }) => {

  return isMember ? (
    <p className={styles.memberDesc}>Hi Member!</p>
  ) : (
    <p>Make An Account Today!</p>
  );
};

function UserCard() {
  const user = useContext(UserContext);
  const userLink = 'www.google.com';

  // check compatibility
  const isCompatible = user.formats?.some(format => format === 'verified');
  const isMember =
    user.info && user.info[0].accountData?.data?.type === 'member';
  if (!isCompatible || user.language !== 'en') {
    return null;
  }

  return (
    <div className={styles.userCard}>
      <div className={styles.title}>Welcome!</div>
      <UserLogo isMember={isMember} />
      <UserDesc isMember={isMember} />
      <a
        className={styles.userLink}
        href={userLink}
      >
        Click Here!
      </a>
    </div>
  );
}

export default UserCard;

At the moment I have these tests:

import React from 'react';
import { mount } from 'enzyme';
import UserCard from '.';
import UserDesc from '.';
import { UserProvider } from '../../contexts/user';

function UserCardWithUser(props) {
  const user = {
    id: '12345',
  };

  return (
    <UserProvider value={{ ...buzz, ...(props.buzz || {}) }}>
      <UserCard />
    </UserProvider>
  );
}

jest.mock('react', () => {
  return {
    ...jest.requireActual('react'),
    useContext: jest.fn(),
  };
});

describe('user card', () => {
  beforeEach(async () => {
    jest.resetAllMocks();
    React.useContext.mockReturnValue({
      getExperimentValue: jest.fn().mockReturnValue('control'),
    });
  });

  it('should render on eligable user', () => {
    const user = {
      formats: ['verified'],
      info: [
        {
          accountData: {
            data: {
              type: 'member',
            },
          },
        },
      ],
      language: 'en'
    };
    const component = mount(<UserCardWithUser user={user} />);
    component.update();
    expect(component.find('UserCard').exists()).toBe(true);
  });

  it('should not render when user is ineligible', () => {
    const userParts = [
      {
        bfpFormats: ['na'],
        formats: [
          {
            accountData: {
              data: {
                type: 'member',
              },
            },
          },
        ],
        language: 'en'
      },
    ];

    for (const userPart of userParts) {
      const component = mount(<UserCardWithUser user={userParts} />);
      component.update();
      expect(component.isEmptyRender()).toBe(true);
    }
  });
});

However I want to be able to test the conditional rendering that is involved within the UserLogo and UserDesc. I have tried this:

 const isMember = true;
    const component = mount(<UserDesc isMember={isMember}/>);
    expect(component.exists('.memberDesc')).toBe(true);

To check that the classname is there when isMember is true but it doesn't seem to be finding the classname.. I am wondering if this is because of the css selector 'styles.'?

You could try console.log(component.find('p').debug()) before your expect statement to see exactly how the style is being displayed in the test. Then you should be able to see what selector to look for in your expect .

I wasn't able to get a.scss file imported in the same way as you had, but this was my testing file and output.

Style.test.tsx

import React, { FC } from 'react';
import { mount } from 'enzyme';
import '../styles/index-styles.scss';

const UserDesc: FC<{ isMember: boolean }> = ({ isMember }) => {
    return isMember ? <p className={'memberDesc'}>Hi Member!</p> : <p>Make An Account Today!</p>;
};

test('UserDesc renders with style if true', () => {
    const isMember = true;
    const component = mount(<UserDesc isMember={isMember} />);
    console.log(component.find('p').debug());
    expect(component.find('.memberDesc')).toHaveLength(1);
});

test('UserDesc does not render with style if false', () => {
    const isMember = false;
    const component = mount(<UserDesc isMember={isMember} />);
    console.log(component.find('p').debug());
    expect(component.find('.memberDesc')).toHaveLength(0);
});

Output

PASS  src/__test__/ClassTest.test.tsx
 ● Console

console.log
  <p className="memberDesc">
    Hi Member!
  </p>

  at Object.<anonymous> (src/__test__/ClassTest.test.tsx:12:13)

console.log
  <p>
    Make An Account Today!
  </p>

  at Object.<anonymous> (src/__test__/ClassTest.test.tsx:19:13)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM