3

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.'?

1 Answer 1

2

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)
Sign up to request clarification or add additional context in comments.

3 Comments

Hi, I tried this but all it prints out for me is <UserDesc isMember={isMember}/> . I tried console.log(component).debug() also and this just printed out React Wrapper {}
Ahh right, you need to get the <p> element because that is where the conditional style will appear. So you will need to do console.log(component.find('p').debug()) I believe
I updated my answer with working code. I wasn't able to import the .scss file in the same way you had, but hopefully you can now plug in the same debug() line to see how using styles in that way will be added to the style property

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.