Skip to content

My Battle With Jest Mocks and Firebase Auth

3 min read
#Testing#Jest#React Native#Firebase#JavaScript

Learn how a subtle mistake in mocking Firebase Auth with Jest caused hours of debugging — and the simple fix that made it all work. A must-read for React Native developers writing unit tests with external libraries.

Why is this mockResolvedValue not working?! That was me — staring at my terminal, debugging the same Jest test for the third hour in a row.

This is the story of how a small mistake in mocking @react-native-firebase/auth cost me hours of testing frustration, and what I learned that finally fixed it.


The Setup

I was writing tests for a sign-up screen in a React Native app. The component uses Firebase Auth to create a new user:

import auth from '@react-native-firebase/auth';

const signUp = async (email: string, password: string) => {
  const userCredential = await auth().createUserWithEmailAndPassword(email, password);
  return userCredential.user;
};

Seems straightforward enough, right? All I needed was to mock auth() so I could control what createUserWithEmailAndPassword returned in my tests.

So I wrote this:

jest.mock('@react-native-firebase/auth', () => {
  return () => ({
    createUserWithEmailAndPassword: jest.fn(),
  });
});

In my test:

(auth().createUserWithEmailAndPassword as jest.Mock).mockResolvedValue({
  user: { uid: 'abc123', email: 'test@example.com' }
});

I expected the test to pass. But instead…

💥 TypeError: Cannot read property 'mockResolvedValue' of undefined

Huh? That didn’t make sense. I was mocking the function… wasn’t I?


The Confusing Part

I tried console logging, debugging, even reading Firebase’s and Jest’s docs again. It seemed like createUserWithEmailAndPassword existed — but my test couldn't spy on it or set any return values.

After a lot of trial and error, I found this tiny difference that made all the difference:

✅ Working version:

const mockCreateUser = jest.fn();

jest.mock('@react-native-firebase/auth', () => {
  return () => ({
    createUserWithEmailAndPassword: mockCreateUser,
  });
});

Boom. It worked. The test passed.


What Was Going Wrong?

In my original version, I did this:

createUserWithEmailAndPassword: jest.fn();

The problem? That creates a new mock function every time auth() is called. So when I tried to modify the mock later with .mockResolvedValue(...), it had no effect — I was modifying a different instance than the one actually used.

But in the fixed version, I stored the mock function in a shared variable:

const mockCreateUser = jest.fn();

That way, every call to auth() returns the same mock — and I can control it from my test.


Lesson Learned

This bug taught me a valuable (and slightly painful) lesson:

Always define your mock functions outside of your mock factory if you need to spy on or modify them.

It’s such a subtle thing, but crucial for mocking effectively — especially with dependencies that return functions like auth().


TL;DR

  • ❌ Don’t inline your jest.fn() inside the returned object from jest.mock
  • ✅ Do define it in a variable outside, and return that reference
  • 🧠 Why? You need a shared reference so your test can modify it

Final Thoughts

This might seem like a small mistake, but it highlights how tricky mocking can get in real-world projects — especially with third-party SDKs.

If you're stuck on a Jest mock that “should work,” but doesn't — check if you’re accidentally recreating mocks every time.

Sometimes, the fix is just one const away.

Want Firebase integrated and properly tested? See my Firebase development for React Native.

Let's bring your app idea to life

React Native apps for iOS & Android, from first commit to the store.

Share this article

Related Articles