Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

420
Vistas
How to test setState inside Firebase Auth onAuthStateChanged

I have already mocked Firebase onAuthStateChanged, so tests work flawlessly but I have this use case, in which it set's the user inside:

const [isSignedIn, setIsSignedIn] = useState<boolean>(false);
const [displayName, setDisplayName] = useState<string | null>('');
const auth = getAuth();
onAuthStateChanged(auth, (user) => {
console.log('OnAuthStateChanged USER', user);
if (user) {
  setDisplayName(user.email);
  setIsSignedIn(true);
} else {
  setIsSignedIn(false);
  setDisplayName('');
}

I know that you can easily mock what it returns, but I don't know how to deal with the "insides" of a function if that it's even possible.

I need to set the state specifically since the DrawerNavigator will show different options depending if the user is signedIn or not:

 {isSignedIn && (
      <>
        <Drawer.Screen name='Dashboard' component={Dashboard} />
      </>
    )}
    {!isSignedIn && (
      <>
        <Drawer.Screen name='Welcome' component={Welcome} />
        <Drawer.Screen name='CreateAccount' component={CreateAccount} />
        <Drawer.Screen name='Login' component={Login} />
      </>
    )}

I can test the functionality but only on the default state as it is initialized, how can I make this work? Or is there any other change of how I set the state in which this could be testable?

Here it is also how I'm mocking firebase/auth module right now:

/**
* Firebase
*/
jest.mock('firebase/auth', () => {
   return {
     getAuth: () => jest.fn(),
     onAuthStateChanged: () => jest.fn(),
   };
});
about 4 years ago · Juan Pablo Isaza
1 Respuestas
Responde la pregunta

0

Assuming you want to emulate the delay that occurs when signing in a user:

  • You must invoke the callback passed as the argument to onAuthStateChanged with or without a user.
  • The currentUser property on the FirebaseAuth instance passed in to it should be updated at the same time.

The mock below assumes you aren't using more than one app at a time. If so, getting specific app instances must be implemented.

/**
* Firebase Auth Module
*/
jest.mock('firebase/auth', () => {
   const authInstance = {
     // while handshaking with the Firebase Auth servers, currentUser
     // is null, regardless if someone is logged in or not.
     currentUser: null
   };

   const mockedUserInfo = Object.freeze({ // force read-only
     // mocked user info here - display name, email, etc
     email: 'example@example.com'
   });
   
   // container for attached callbacks and state variables
   const authChangeCallbacks = [];
   let authCurrentUserInfo = mockedUserInfo;
   let authTimer = null;
   let authTimerCompleted = false;

   // invoke all callbacks with current data
   const fireOnChangeCallbacks = () => {
     authMock.currentUser = authCurrentUserInfo;
     callbacks.forEach((cb) => {
       try {
         cb(mockedUserInfo)); // invoke any active listeners
       } catch (err) {
         console.error('Error invoking callback', err);
       }
     });
     authTimerCompleted = true;
   }

   authInstance.signOut = () => { // signInWithX will look similar to this
     authCurrentUserInfo = null;
     fireOnChangeCallbacks();
   };

   return {
     getAuth: jest.fn(() => authInstance),
     onAuthStateChanged: jest.fn((authMock, onChangeCallback) => {
       if (!authTimer) {
         // increase this delay to emulate slower connections
         authTimer = setTimeout(fireOnChangeCallbacks, 2000);
       }

       callbacks.push(onChangeCallback);
       const unsubscriber = () => {
         const foundIndex = callbacks.indexOf(onChangeCallback);
         if (foundIndex > -1) callbacks.splice(foundIndex, 1);
       }

       if (authTimerCompleted) {
         // auth is "resolved" already, fire callback immediately
         onChangeCallback(mockedUserInfo);
       }

       return unsubscriber;
     })
   };
});
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda