2

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.

Whiz
  • 77
  • 1
  • 7
  • Does this answer your question? [In Jest, how can I unit test a method that subscribes to an observable](https://stackoverflow.com/questions/58815471/in-jest-how-can-i-unit-test-a-method-that-subscribes-to-an-observable) – mainak Jul 25 '22 at 17:34

1 Answers1

0

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();
})
Abe
  • 4,500
  • 2
  • 11
  • 25
  • Hi. Thank you very much for the reply but I am keep getting `Argument of type string is not assignable to parameter of type never` in `const authStateSpy = jest.spyOn(useAuthState, 'default');` – Whiz Jul 26 '22 at 02:10
  • can you post your code? I use this often and it works for me. Jest has a similar example [in their docs](https://jestjs.io/docs/jest-object#jestspyonobject-methodname). – Abe Jul 26 '22 at 05:28
  • Can you check now? I have posted code for useAuthState hook and others – Whiz Jul 26 '22 at 07:04
  • Any luck bro? I am just helpless now – Whiz Jul 26 '22 at 16:37
  • where's the code that gave you the error above? I don't see any code with spyOn – Abe Jul 26 '22 at 19:56