[go: nahoru, domu]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using jest.useFakeTimers() in a test causes firebase-admin/firestore promises to no longer resolve #2283

Open
curtis-jotson opened this issue Aug 15, 2023 · 8 comments
Assignees

Comments

@curtis-jotson
Copy link

[READ] Step 1: Are you in the right place?

  • For issues related to the code in this repository file a Github issue.
  • If the issue pertains to Cloud Firestore, read the instructions in the "Firestore issue"
    template.
  • For general technical questions, post a question on StackOverflow
    with the firebase tag.
  • For general Firebase discussion, use the firebase-talk
    google group.
  • For help troubleshooting your application that does not fall under one
    of the above categories, reach out to the personalized
    Firebase support channel.

[REQUIRED] Step 2: Describe your environment

  • Operating System version: MacOS 13.5
  • Firebase SDK version: ^11.9.0
  • Firebase Product: firebase-admin/firestore
  • Node.js version: 18.17.0
  • NPM version: 9.8.1

[REQUIRED] Step 3: Describe the problem

Steps to reproduce:

Set up a jest test against firebase-admin/firestore running against a local emulator. If faking out date and timers with jest.useFakeTimers(), a very common way of date/time mocking, suddenly Firebase promises are no longer resolving. Date mocking and faking is very common in the TDD world and the data access library should continue to respond even if "time" isn't moving.

Relevant Code:

  1. Set up a new NPM project and install jest and firebase-admin
  2. Start a Firestore emulator, you can use a different project for this, I didn't include it for simplicity (you could also use an online instance)
  3. Change the PROJECT_ID in the following test file to the projectId the emulator is running for
  4. Run the test with jest, it should pass and add a test document to a test collection
  5. Uncomment the jest.UseFakeTimers() call in beforeAll
  6. Run the test again, it will time-out
process.env.FIRESTORE_EMULATOR_HOST = "127.0.0.1:8080"

const admin = require('firebase-admin')
const { getFirestore } = require('firebase-admin/firestore')

admin.initializeApp({ projectId: "PROJECT_ID" })

const db = getFirestore()

describe('', () => {
    beforeAll(() => {
        // jest.useFakeTimers()
    })

    afterAll(() => {
        jest.useRealTimers()
    })

    test('', async () => {
        await db.collection('test').add({ test: "I am a test document" })
    })
})
@google-oss-bot
Copy link

I couldn't figure out how to label this issue, so I've labeled it for a human to triage. Hang tight.

@cherylEnkidu
Copy link
cherylEnkidu commented Aug 15, 2023

Hi @curtis-jotson , can you explain more which part of the code experiences time out? For example,

afterAll(() => {
    // put some logs here to see if the line reaches
    jest.useRealTimers()
})

Or

test('', async () => {
    await db.collection('test').add({ test: "I am a test document" })
    // put some logs here to see if the line reaches
})

@curtis-jotson
Copy link
Author

Hello @cherylEnkidu, sorry for the delay.

This part experiences the timeout:

test('', async () => {
    await db.collection('test').add({ test: "I am a test document" })
    // put some logs here to see if the line reaches
})

when this part is uncommented:

    beforeAll(() => {
        // jest.useFakeTimers()
    })

@cherylEnkidu
Copy link

Hi @curtis-jotson , it could be possible that faking time changes some underlining javascript and unfortunately we can only guaranteeing the performance on production environment.

@curtis-jotson
Copy link
Author

It does this when connected to the online environment as well, not just the emulators. It's an issue with library halting data access when "time" isn't moving. No other data access library I've used exhibits this behaviour and it's stopping me from being able to TDD my code effectively.

@cherylEnkidu
Copy link

Sorry for the confusion here. The team can only guarantee the performance on the production environment which including using the real time. It is possible changing the system time fails some of the security checks in the backend.

@maemae-dev
Copy link

I encountered the same problem as this one. I only wanted to mock new Date(), so by providing everything except for Date, which is mentioned at https://jestjs.io/ja/docs/jest-object#jestusefaketimersfaketimersconfig, to the doNotFake option, the test started working

jest.useFakeTimers({
      doNotFake: [
        "hrtime",
        "nextTick",
        "performance",
        "queueMicrotask",
        "requestAnimationFrame",
        "cancelAnimationFrame",
        "requestIdleCallback",
        "cancelIdleCallback",
        "setImmediate",
        "clearImmediate",
        "setInterval",
        "clearInterval",
        "setTimeout",
        "clearTimeout",
      ],
      now: new Date("2022/01/01 0:00:00"),
    });

@vojdan
Copy link
vojdan commented Apr 12, 2024

I encountered the same problem as this one. I only wanted to mock new Date(), so by providing everything except for Date, which is mentioned at https://jestjs.io/ja/docs/jest-object#jestusefaketimersfaketimersconfig, to the doNotFake option, the test started working

jest.useFakeTimers({
      doNotFake: [
        "hrtime",
        "nextTick",
        "performance",
        "queueMicrotask",
        "requestAnimationFrame",
        "cancelAnimationFrame",
        "requestIdleCallback",
        "cancelIdleCallback",
        "setImmediate",
        "clearImmediate",
        "setInterval",
        "clearInterval",
        "setTimeout",
        "clearTimeout",
      ],
      now: new Date("2022/01/01 0:00:00"),
    });

Woah thanks! I've been struggling with this for a long time!! I had to mock out Date.now() as a workaround previously.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants