How to test a component that is conditionally rendered based on a hook value?

Viewed 118

I am working on a React Native application and am very new to testing. I am trying to mock a hook that returns a true or false boolean based on the current user state. I need to mock the return value of the authState variable, and based on that, I should check if the component is rendered or not. But the jest mock is returning the same value only

useAuth.ts

export const useAuthState = () => {
  const [authState, setAuthState] = useState<AuthState>();

  useEffect(() => {
    return authentication.subscribe(setAuthState);
  }, []);

  return authState;
};

MyComponent.tsx

export const MyComponent = () => {

    const authState = useAuthState();

    if (!authState) {
        return null;
      }
    
     return <AnotherComponent />
}

MyComponent.test.tsx

import { MyComponent } from "./MyComponent"

jest.mock('../use-auth-state', () => {
    return {
        useAuthState: () => false,
    };
});

const TestComponent = () => <MyComponent />

describe('MyComponent', () => {
    it('Should return null if the authState is null', () => {

        let testRenderer: ReactTestRenderer;

        act(() => {
            testRenderer = create(<TestComponent />);
        });

        const testInstance = testRenderer.getInstance();
        expect(testInstance).toBeNull()
    })
})

This is working fine. But, I am not able to mock useAuthState to be true as this false test case is failing. Am I doing it right? I feel like I am messing up something.

1 Answers

You want to change how useAuthState is mocked between tests, right? You can set your mock up as a spy instead and change the mock implementation between tests.

It's also a little more ergonomic to use the render method from react-testing-library. The easiest way would be to give your component a test ID and query for it. Something like the below

import { MyComponent } from "./MyComponent"
import * as useAuthState from '../use-auth-state';

const authStateSpy = jest.spyOn(useAuthState, 'default');

describe('MyComponent', () => {
  it('Should return null if the authState is null', () => {
    // you can use .mockImplementation at any time to change the mock behavior
    authStateSpy.mockImplementation(() => false);

    const { queryByTestId } = render(<MyComponent />;
    expect(queryByTestId('testID')).toBeNull();
})
Related