react-native-testing-library icon indicating copy to clipboard operation
react-native-testing-library copied to clipboard

Incorrect automatic cleanup order

Open alpha0010 opened this issue 1 year ago • 1 comments

Describe the bug

While running tests, I get:

ReferenceError: You are trying to access a property or method of the Jest environment after it has been torn down.

This appears to be due to the useEffect() cleanup being called after Jest has done its own cleanup; manually unmount()ing the component before exiting the test resolves the issue.

This is problematic since jest --runInBand exits non-zero, causing pipeline failures (even though all tests pass).

Expected behavior

Automatic cleanup has access to the Jest environment, so I do not need to manually unmount().

Steps to Reproduce

// Add to `MyComponent`
  useEffect(() => {
    const handle = InteractionManager.runAfterInteractions(async () => {
      let nextFrame = new Promise((resolve) => requestAnimationFrame(() => resolve()));
      await nextFrame();
    });
    return () => {
      handle.cancel();
    };
  }, []);
test('Render example', async () => {
  const {toJSON, unmount} = render( <MyComponent /> );

  expect(toJSON()).toMatchSnapshot();

  // Uncomment to resolve access Jest environment after teardown.
  //unmount();
});

Screenshots

Versions

  npmPackages:
    @testing-library/react-native: ^12.4.3 => 12.4.3 
    react: 18.2.0 => 18.2.0 
    react-native: 0.73.4 => 0.73.4 
    react-test-renderer: 18.2.0 => 18.2.0 

alpha0010 avatar Feb 15 '24 21:02 alpha0010

@alpha0010 thank you for reporting this.

As far as I can see:

  • RNTL enqueues unmount for cleanup queue: https://github.dev/callstack/react-native-testing-library/blob/main/src/cleanup.ts
  • cleanup queue is cleared in the cleanup phase: https://github.com/callstack/react-native-testing-library/blob/4e148bdb0573fcb86686482c3af1d1e02e1cc937/src/cleanup.ts#L7C25-L7C32
  • cleanup is triggered by default in afterEach Jest event: https://github.com/callstack/react-native-testing-library/blob/4e148bdb0573fcb86686482c3af1d1e02e1cc937/src/index.ts#L13

What you are doing in the workaround is that you are calling unmount() directly in the test, so before afterEach. That causes the useEffect cleanup be called inside the test, and not in "after test" phase.

I'm not sure if cleanup could technically be called by RNLT "inside" the test, as that is controlled by Jest (and you as the user). So the manual unmount() workaround seems the best we can do now. Let me know if you see other options.

mdjastrzebski avatar Mar 12 '24 08:03 mdjastrzebski

Closing as stale. Workaround available (manual calling of unmount.

mdjastrzebski avatar May 23 '24 11:05 mdjastrzebski