Search code examples
reactjsunit-testingjestjsvitets-jest

How to test conditional rendering provided a method that returns boolean?


I'm wanting to test a conditional rendering, but I'm having trouble getting the function (userHasAccess) from the custom hook and simulating a return of true, so that the element is rendered on screen.

useData.tsx

import React from 'react';

const useData = () => {

  function userHasAccess(access: 'student' | 'teacher' | 'admin'): boolean {
    return getLoggedUser()?.access === access
  }

  others functions...

  return {
    userHasAccess,
    others functions...
  }
}

export default useData;

Sidebar.tsx

const Sidebar = () => {
  const { userHasAccess } = useData();

  return (
      <ul>
        {userHasAccess('admin') && <li><Link to='usuarios'>Users</Link></li>}
      </ul>
    </nav>
  )
}

export default Sidebar;

Sidebar.test.tsx

  it('should render correctly for admin', () => {
    render(<BrowserRouter><Sidebar /></BrowserRouter>)

    expect(screen.getByText("Users")).toBeInTheDocument();

  })
})

How can I test in this situation so that:

expect(screen.getByText("Users")).toBeInTheDocument();

Pass the test?


Solution

  • As far as I understood, you just to need mock userHasAccess to return true value

    Try the code below:

    // Sidebar.test.tsx
    
    import React from 'react';
    import { render, screen } from '@testing-library/react';
    import { BrowserRouter } from 'react-router-dom';
    import Sidebar from './Sidebar'; 
    import useData from './useData';
    
    jest.mock('./useData');
    
    describe('Sidebar', () => {
      afterEach(() => {
        jest.clearAllMocks();
      });
    
      it('should render correctly for admin', () => {
        useData.mockReturnValue({ userHasAccess: jest.fn().mockReturnValue(true) });
    
        render(
          <BrowserRouter>
            <Sidebar />
          </BrowserRouter>
        );
    
        expect(screen.getByText('Users')).toBeInTheDocument();
      });
    });