callstack / react-native-testing-library

🦉 Simple and complete React Native testing utilities that encourage good testing practices.
https://callstack.github.io/react-native-testing-library/
MIT License
3.01k stars 264 forks source link

unstable_validateStringsRenderedWithinText immediate setState in useEffect #1611

Closed precious-void closed 1 month ago

precious-void commented 1 month ago

Describe the bug

When immediately calling setState in useEffect and the component is rendered with unstable_validateStringsRenderedWithinText parameter, the following error is thrown:

    `render` method has not been called

       5 |
       6 | const notImplemented = () => {
    >  7 |   throw new Error(SCREEN_ERROR);
         |         ^
       8 | };
       9 |
      10 | const notImplementedDebug = () => {

      at Object.notImplemented (src/screen.ts:7:9)
      at toJSON (src/render.tsx:71:48)
      at commitLayoutEffectOnFiber (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:13282:15)
      at commitLayoutMountEffects_complete (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14330:9)
      at commitLayoutEffects_begin (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14316:7)
      at commitLayoutEffects (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:14301:3)
      at commitRootImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16062:5)
      at commitRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15933:5)
      at performSyncWorkOnRoot (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:15454:3)
      at flushSyncCallbacks (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:2597:22)
      at flushPassiveEffectsImpl (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16261:3)
      at flushPassiveEffects (node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16197:14)
      at node_modules/react-test-renderer/cjs/react-test-renderer.development.js:16012:9
      at flushActQueue (node_modules/react/cjs/react.development.js:2667:24)
      at act (node_modules/react/cjs/react.development.js:2521:11)
      at actImplementation (src/act.ts:30:25)
      at renderWithAct (src/render-act.ts:12:11)
      at renderWithStringValidation (src/render.tsx:81:33)
      at renderWithStringValidation (src/render.tsx:52:12)
      at renderInternal (src/render.tsx:29:10)

Expected behavior

I would expect it not to throw, as without this unstable parameter it does work.

Steps to Reproduce

const UseEffectComponent = () => {
  const [showText, setShowText] = React.useState(false);

  React.useEffect(() => {
    setShowText(true);
  }, []);

  if (!showText) {
    return <Text>Text is hidden</Text>;
  }

  return (
    <View>
      <Text>text rendered outside text component</Text>
    </View>
  );
};

test('should render properly', async () => {
  render(<UseEffectComponent />, { unstable_validateStringsRenderedWithinText: true });

  expect(await screen.findByText('text rendered outside text component')).toBeTruthy();
});

I added this test in https://github.com/callstack/react-native-testing-library/blob/bab4097836aa903ff4cc3cd441bf99252f623cf5/src/__tests__/render-string-validation.test.tsx And it does fail even there.

Versions

npmPackages: react: 18.2.0 => 18.2.0 react-native: 0.74.1 => 0.74.1 react-test-renderer: 18.2.0 => 18.2.0

mdjastrzebski commented 1 month ago

@precious-void thank you for noting and fixing that. BTW have you spotted that edge case while actually writing tests? or you just figured out that we are missing edge case support?

precious-void commented 1 month ago

@mdjastrzebski hey, thanks for a quick reply, yeah, I had spotted it while writing tests and couldn't understand why it would throw an error. As a workaround I'm temporarily not using this flag.

mdjastrzebski commented 1 month ago

This issue has been fixed in v12.5.1 🎉