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

When testing a Navigation container with jest the test passes, but the process fails #9568

Closed
emmarq opened this issue May 10, 2021 · 8 comments

Comments

@emmarq
Copy link

emmarq commented May 10, 2021

Current Behavior

The test succeeds, but the process fails. This is the output:

ReferenceError: You are trying to `import` a file after the Jest environment has been torn down.

      at Object.get Linking [as Linking] (node_modules/react-native/index.js:241:12)
      at node_modules/@react-navigation/native/lib/commonjs/useLinking.native.tsx:121:15
      at Object.invokeGuardedCallbackProd (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11308:10)
      at invokeGuardedCallback (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:11499:31)
      at flushPassiveEffectsImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14560:11)
PASS __tests__/Navigation.test.js (15.215 s)
  ✓ just succeed (3 ms)
  Navigation Container
    ✓ run test without importing a file after it (236 ms)

Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        15.333 s
Ran all test suites matching /Navigation/i.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
Error: Process completed with exit code 1.

I haven´t found out why there is this ReferenceError. Even disabling linking it still happens.

Expected Behavior

The proccess should finish with no error code.

How to reproduce

This is the file with a simple test.

https://github.com/emmarq/RnReplica/blob/main/__tests__/Navigation.test.js

You can look the action with the result.

https://github.com/emmarq/RnReplica/runs/2547893152?check_suite_focus=true

Your Environment

software version
iOS or Android N/A
@react-navigation/native ^5.9.4
react-native 0.64
expo N/A
node 12.16.3
npm or yarn 1.22.0
   "@testing-library/react-native": "^7.2.0",
    "babel-jest": "^26.6.3",
    "jest": "^26.6.3",
    "react-test-renderer": "^17.0.2"

Thank you for the help.

@emmarq emmarq added the bug label May 10, 2021
@github-actions
Copy link

Hey! Thanks for opening the issue. The issue doesn't seem to contain a link to a repro (a snack.expo.io link or link to a GitHub repo under your username).

Can you provide a minimal repro which demonstrates the issue? A repro will help us debug the issue faster. Please try to keep the repro as small as possible and make sure that we can run it without additional setup.

@emmarq
Copy link
Author

emmarq commented May 10, 2021

Hey! Thanks for opening the issue. The issue doesn't seem to contain a link to a repro (a snack.expo.io link or link to a GitHub repo under your username).

Can you provide a minimal repro which demonstrates the issue? A repro will help us debug the issue faster. Please try to keep the repro as small as possible and make sure that we can run it without additional setup.

https://github.com/emmarq/RnReplica

@satya164
Copy link
Member

You'd need to use jest.useFakeTimers(); in your tests

@emmarq
Copy link
Author

emmarq commented May 10, 2021

You'd need to use jest.useFakeTimers(); in your tests

Thank you for the response. I tried that in the minimal case i built and it worked.

But in the real case, which handles various async tasks, the test timeouts with the addition of jest.useFakeTimers();; without it it passes but still raises the exit code 1.

@emmarq
Copy link
Author

emmarq commented May 10, 2021

Alright, i took the time to try to understand what useFakeTimers do, i was hesitant to use it because its big impact on all async tasks. So far it turns out that i might need to refactor my tests.

The example goes like this

 it('run test without importing a file after it', async () => {
    const { getByText } = render(<App />);
    await act(async () => {});

    getByText('Go to Screen B');
  });

The changes i think necessary involves removing the asynchronous test. No more async function for it and use the mock timers of jest to accomplish the same behaviour. I understand it like forcing a sync behaviour of async task by "tweaking the time" using the jest api and somehow understanding the moments the side effects happens in the app, those moments are the key indicators where to put, or not to put the timer modifications.

jest.useFakeTimers();
 it('run test without importing a file after it', () => {
    const { getByText } = render(<App />);
    act(() => jest.runAllTimers()); // In the case of an app with side effects on mount, 
                                    // this will trigger them in a safe context, rigth? 
                                    // in the case of another effects triggered by 
                                    // the press of a button, for example, 
                                    // i guess this would be neccesary as well.

    getByText('Go to Screen B');
  });

This line act(() => jest.runAllTimers()); and previously this one await act(async () => {}); is there to avoid the warning An update to ForwardRef(NavigationContainer) inside a test was not wrapped in act(...) in my actual test case. https://stackoverflow.com/questions/61695139/async-testing-react-navigation-5-in-jest-navigationcontainer-causes-console-err

I am now asking if this is the best way to go to fix the issue. Or is there any better alternative?

@emmarq
Copy link
Author

emmarq commented May 11, 2021

Ok, i am closing this as my issue is resolved now, but before doing it, i hit one more problem with the animations of some navigators and the fake timers. I ended up following this comment jestjs/jest#5147 (comment)

Maybe this can be of little to someone else.

@emmarq emmarq closed this as completed May 11, 2021
@jehartzog
Copy link

@emmarq I was able to resolve this without using fake timers using the mock:

jest.mock('@react-navigation/native/lib/commonjs/useLinking.native', () => ({
  default: () => ({getInitialState: {then: jest.fn()}}),
  __esModule: true,
}));

@github-actions
Copy link

Hey! This issue is closed and isn't watched by the core team. You are welcome to discuss the issue with others in this thread, but if you think this issue is still valid and needs to be tracked, please open a new issue with a repro.

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

3 participants