Having difficulty running unit tests on a styled component that is overriding material-ui

In my project, I have a customized styled component for a navigation list item which is wrapped around a Material-UI list item. To override the default styles without using '!important' flags, I am utilizing the '&&' operator in the styling.

import { ListItem } from 'material-ui/List'

export const StyledNavListItem = withTheme()(styled(ListItem)`
  && {
    background: ${props => props.selected
    ? props.theme.palette.backgrounds.selected
    : 'inherit'};
  }
`)

The implementation of this styled component looks like this:

export const NavListItem = props => {
  return (
    <StyledNavListItem selected={props.selected} component={Link} to={props.to || ''} onClick={props.onClick || (() => false)} button>
      {props.icon && <ListItemIcon><Icon name={props.icon} /></ListItemIcon>}
      <ListItemText primary={props.children || ''} />
    </StyledNavListItem>
  )
}

However, when attempting to perform unit testing (using Jest, enzyme, and jest-styled-components), I encounter an issue:

it('should change the background color of an item if `props.selected` is truthy', () => {
    const navList = mount(
      <MuiThemeProvider theme={theme}>
        <BrowserRouter>
          <Route>
            <NavList>
              <NavListItem>item text</NavListItem>
              <NavListItem selected>item text</NavListItem>
            </NavList>
          </Route>
        </BrowserRouter>
      </MuiThemeProvider>
    )
    expect(navList.find(StyledNavListItem).at(0)).toHaveStyleRule('background', '#e0e0e0')
    expect(navList.find(StyledNavListItem).at(1)).toHaveStyleRule('background', theme.palette.backgrounds.selected)
  })

An error message is displayed stating Property not found: "background". Interestingly, removing the '&&' wrapper from the styles allows the tests to pass smoothly, but then the component doesn't reflect the desired styles. Is there a way to access and test the overrides within that block?

Answer №1

After much experimentation, I managed to find a solution. By defining custom classes within the material-ui component and then referencing them in the styles section, everything worked flawlessly even with added modifiers.

Illustration Typography.style.js

import React from 'react'
import { withTheme } from 'material-ui/styles'
import styled, { css } from 'styled-components'
import Typography from 'material-ui/Typography'

export const StyledTypography = withTheme()(styled(({emphasized, strong, inlined, color, ...other}) => {
  return <Typography {...other} classes={{root: 'typography-root'}} />
})`
  &.typography-root {
    line-height: 1.2em;
    ${props => !props.variant && css`
      font-size: 1em;
    `}
    ${props => props.color && props.theme.palette.typography[props.color] && css`
      color: ${props.theme.palette.typography[props.color]};
    `}
    ${props => props.strong && css`
      font-weight: 500;
    `}
    ${props => props.emphasized && css`
      font-style: italic;
    `}
    ${props => props.inlined && css`
      display: inline-block;
    `}
  }
`)

Test

it('performs an action', () => {
    const typography = mount(
      <MuiThemeProvider theme={praxisTheme}>
        <Typography />
      </MuiThemeProvider>
    )
    expect(typography.find(MaterialUITypography)).toHaveStyleRule('line-height', '1.2em', { modifier: '&.typography-root' })
})

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Icon of Material Design with rectangular backdrop

I am having trouble locating any instructions on producing an icon with rectangular backgrounds similar to what is shown here: https://i.stack.imgur.com/3vkZN.png I have not come across any properties for <Icon /> or <SvgIcon /> that would ac ...

The validation of the form does not seem to be functioning properly when the 'required' rule is used

I have implemented the Required form validation in my input fields to prevent submission with empty data. However, it seems like my required validation is not functioning as expected. function AddCar() { const [chasis, setChasis] = useState("" ...

Navigating through sections in NextJS-14: Utilizing useRef for seamless scrolling

In the past, I had developed an older portfolio website using Vite React + TS and implemented useRef for scrolling to sections from the Navbar. Now, my goal is to transition this portfolio to NextJS 14. I transferred my old components and style folders in ...

Transferring information from a React form to an ExpressJS backend and then seamlessly redirecting to the PayuMoney platform for secure payment processing

Challenge Overview : I am currently working on the integration of payuMoney in a website built with ReactJS, NodeJS, and Express. The goal is to create a form where users can input their data, and then pass this information to the backend API located in in ...

Transferring information from offspring to parent

Greetings! I'm currently getting my feet wet with React and finding myself stuck on an issue regarding passing states. Is it possible for me to pass a child state to a parent component in order to selectively render other child components? ...

Redirect Conditions in NextJS

One scenario: a blog with an extensive library of content cataloged by Google. Every piece is accessible via www.site.com/post1. When migrating this blog to NextJS, the posts are now located at www.site.com/blog/post1. Redirects using 301 have successful ...

Creating unique appbars for different sections on my sidebar in ReactJs

I am trying to implement a responsive drawer and AppBar using material-ui (@material-ui/core). My goal is to display a specific AppBar for each section of the drawer. For instance, when the user navigates to the Timetable section, I want the AppBar label t ...

Using the set method to assign identical values within a Record object results in the creation of a distinct new

I have implemented Immutable Record in ReduceStore to prevent emitting changes when there is no actual data change. However, I am facing an issue where even for the same data, Immutable.js creates a new object causing the ReduceStore `areEqual` function to ...

Issue encountered when executing 'react-native link': 'Dependency not recognized'

I'm currently working on developing a video chat feature for my project, following this example: To kickstart the project, I created a new one using: npx react-native init AwesomeProject Next, I added the necessary dependencies: npm install --save ...

What is the process for retrieving the address of the connected wallet using web3modal?

I've been working on an application using next.js and web3. In order to link the user's wallet to the front-end, I opted for web3modal with the following code: const Home: NextPage = () => { const [signer, setSigner] = useState<JsonRpcSig ...

Setting MUI input value within a loop using an array value in React JS: A step-by-step guide

Recently, I created a React js demo using React MUI. To handle inputs, I created a separate component called InputText.js for each input field. The issue I encountered is when I tried to use this component to display multiple education fields stored in an ...

Following deployment and page building in REACT JS, the pages fail to open

As a student still learning, I'm in need of assistance with a project. When I deploy the system and run the build, the initial page works fine but all redirects fail to work. If you'd like to view the page, it's available at: I'm seei ...

Best practices for implementing useDispatch and bindActionCreators in your project?

I have a question about the placement of certain methods. When using Redux store in multiple components, I find myself repeating the same import process: import { useSelector, useDispatch } from "react-redux"; import { bindActionCreators } from & ...

Tips for Repurposing a React Table

I am in the process of developing my own react component library to be used across my entire application. At the moment, I have started with a table component which is currently undergoing testing. However, I am facing the challenge of calling the componen ...

Properties of the State Object in React Redux

I'm curious as to why my state todos were named todo instead of todos in the redux dev tools. Where did that name come from? There is no initial state, which makes me wonder. I'm currently following a Udemy course by Stephen Grider, but I am wor ...

Within the Next.js 13 application folder, what is the best method for generating new pages incrementally?

My CMS contains a range of items, starting from /items/1 and going all the way up to /items/9999. The content for these items is static, so there's no need to worry about revalidating them. Although new items are added to the CMS frequently throughou ...

What causes React JS to continuously render in an infinite loop when using hooks and useState

I am struggling with updating the current state of my component based on a result using a custom hook in React. Whenever I try to update it, I end up in an infinite loop rendering due to my usage of the useState() hook. I am still new to working with Rea ...

You are unable to utilize global SCSS in Next.js as the Global CSS is restricted to being imported only from files within your Custom <App> component

After setting up node-sass in my next.js application, I attempted to include my global scss file using import '../styles/style.scss'; in the _app.js component, but encountered an error: The system is alerting that Global CSS cannot be imported fr ...

A guide to setting a custom icon for the DatePicker component in Material-UI 5

Seeking to incorporate custom Icons from react-feathers, I have implemented a CustomIcon component which returns the desired icon based on the name prop. Below is the code for this component. import React from 'react'; import * as Icon from &apo ...

Tips for customizing the appearance of the Alert Dialog in React-admin?

React-admin alert dialog example I'm currently working on a React-admin project and I am looking to customize the alert dialog that displays errors, warnings, and success messages on the page. Specifically, I want to apply CSS styles like z-index and ...