Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Need help with unit testing generated classes #157

Open
OlIvAl opened this issue Mar 9, 2023 · 3 comments
Open

Need help with unit testing generated classes #157

OlIvAl opened this issue Mar 9, 2023 · 3 comments

Comments

@OlIvAl
Copy link

OlIvAl commented Mar 9, 2023

Hello there!
I'm using your library in my project. Unfortunately, I couldn't find any examples of writing unit tests for classes generated by the useStyles hook (which returns makeStyles function). For example:

const MenuItem: FC<IProps> = ({
  label,
  url,
  iconSrc,
  active = false,
}) => {
  const { classes, cx } = useMenuItemStyles();
  return (
    <a
      href={url}
      target="_blank"
      rel="noreferrer"
      data-testid="menu-item-link"
      className={cx(
        сlasses.link,
        active && сlasses.active
      )}
    >
      {label}
    </a>
  );
};

it.skip("should render anchor with active class if active prop is true", () => {
  expect.hasAssertions();

  const { getByTestId } = render(
    <ThemeProvider theme={LayoutTheme}>
      <CollapsedMenuItem
        label={label}
        url={url}
        iconSrc={iconSrc}
        active={true}
      />
    </ThemeProvider>
  );

  expect(getByTestId("menu-item-link")).toHaveClass("active");
});

This test, or any other similar test, cannot pass because the active class does not exist. Instead, a class with a hash is generated. Is it possible to control or mock this generation process? In the past, MUI had a StylesProvider where you could set the class name generator using the generateClassName prop.

For example:

const generateClassName: StylesOptions['generateClassName'] = (
  rule,
  sheet
): string => `${sheet?.options.classNamePrefix}-${rule.key}`;

export const provideTheme = (ui: ReactElement): ReactElement => {
  return (
    <ThemeProvider theme={theme}>
      <StylesProvider generateClassName={generateClassName}>
        {ui}
      </StylesProvider>
    </ThemeProvider>
  );
};

I couldn't find similar mechanisms in your library.

@garronej
Copy link
Owner

garronej commented Mar 9, 2023

HI @OlIvAl,

I'll see what I can do but allow me to challange your testing approach.
Why testing for classNames instead of testing for poperties like MUI does?

Because the main strengh of TSS (and Emotion) is to be able to generate the styles dynamically and get rid of
the class witching logic.

const MenuItem: FC<IProps> = ({
  label,
  url,
  iconSrc,
  active = false,
}) => {
  const { classes, cx } = useMenuItemStyles({ active });
  return (
    <a
      href={url}
      target="_blank"
      rel="noreferrer"
      data-testid="menu-item-link"
      className={сlasses.link}
    >
      {label}
    </a>
  );
};

const useMenuItemStyles = makeStyles<{ active: boolean; }>()((theme, { active }) => ({
   link: {
      // generate the style dynamically using active
   }
}));

If I wand to provide a mock I have to be able to generate a fingerprint of the params and the theme state, wich isn't trivial to do safely.

@garronej
Copy link
Owner

garronej commented Mar 9, 2023

Afterthough:
Under the hood of TSS it's emotion.
Let's see what they have in store.
Can you test with this and tell me if it work for you: https://emotion.sh/docs/testing

@julianinsua
Copy link

Well, I checked and Emotion does snapshot testing. This comes at a cost because you have to maintain your code AND the generated snapshots. I know there's convenience to regenerate the snapshots on almost any test engine, but I'd rather monkey patch the makeStyles method. Does someone know how this could be done or approached?

Regardless of my preference for monkey patching, it would be great to have some examples on the docs for unit testing, or testing in general.

Thanks in advance!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants