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

Test fails when using react-navigation container and react-redux provider together #1118

Closed
firasrg opened this issue Sep 14, 2022 · 10 comments

Comments

@firasrg
Copy link

firasrg commented Sep 14, 2022

Hi! I have a weird annoying issue while I try to wrap my component (to render), inside redux provider + navigation container, following the examples such as the one in this Github repo, as for the other example from redux-toolkit repo.

👉 If I combine <NavigationContainer/> with <Provider/> as follows:

    const ComponentToRender = () => (
        <Provider store={mockStore}>
          <NavigationContainer>
             <MyScreenToRender />
          </NavigationContainer>
        </Provider>
    )

I get the following errors:

ERROR 1 🐞:

 console.error
    Warning: An update to MyScreenToRender inside a test was not wrapped in act(...).
    
    When testing, code that causes React state updates should be wrapped into act(...):
    
    act(() => {
      /* fire events that update state */
    });
    /* assert on the output */
    
    This ensures that you're testing the behavior the user would see in the browser. Learn more at https://reactjs.org/link/wrap-tests-with-act

ERROR 2 🐞:

WARN - IDE integration: Couldn't find a navigation context. Have you wrapped your app with 'NavigationContainer'? See https://reactnavigation.org/docs/getting-started for setup instructions.
Error: Couldn't find a navigation context. Have you wrapped your app with 'NavigationContainer'? See https://reactnavigation.org/docs/getting-started for setup instructions.
    at Object.get getIsInitial [as getIsInitial] (...\node_modules\@react-navigation\core\lib\commonjs\NavigationStateContext.tsx:37:11)

This is my test file code :

import {
  screen,
  waitFor,
  render,
} from "@testing-library/react-native";
import { mockStore } from "@app/tests/mock-redux/mockStore";
import { NavigationContainer } from "@react-navigation/native";
import { Provider } from "react-redux";
import apiInstance from "../../api/myApi";
import MyComponentToRender from "../../view";

jest.mock('react-i18next', () => ({
  useTranslation: () => {
    return {
      t: (str:string) => str,
      i18n: {
        changeLanguage: () => new Promise(() => {}),
      },
    };
  },
}));

jest.mock('react-native-reanimated', () => {
  const Reanimated = require('react-native-reanimated/mock');

  Reanimated.default.call = () => {};

  return Reanimated;
});

// Reset RTK API state after each test case
afterEach(() => {
    // following a recommendation from Redux team
    // the RTKQ state, must be reset visit: https://stackoverflow.com/a/69310703/10000150
    mockStore.dispatch(apiInstance.util.resetApiState())
})

// TODO
describe('list screen tests', () => {

  // scenario one : initialize screen
  it('list initialization', async () => {
    
    const ToRender = () => (
        <Provider store={mockStore}>
          <NavigationContainer>
            <MyComponentToRender />
          </NavigationContainer>
        </Provider>
    )
    
    render(<ToRender />);
    
    const screenGlobalLoading = screen.getByText(/loading/, {exact: false});

    expect(screenGlobalLoading).toEqual("Loaading...");
    
    await waitFor(() => {
      expect(screenGlobalLoading).toBeFalsy();
    });
  });
});

I use the following techs:

Tech Version
Expo 45.0.0
React Native v0.68.2
Redux-Toolkit v1.8.2
React Redux v8.0.2
RN Testing Library v10.1.1
react-navigation/native 6.0.2

I can give you further information if needed, please help 🙏

Originally posted by @firas1220 in #1100 (comment)

@mdjastrzebski
Copy link
Member

@firas1220 In general using Provider + NavigationContainer should work.

Re error 1: looks like there might be some automatic re-render that happens due to some async action inside the component which is not triggered by explicitly calling fireEvent. BTW follwing code is incorrect:

    await waitFor(() => {
      expect(screenGlobalLoading).toBeFalsy();
    });

As if you got screenGlobalLoading when it was rendered, then as a const it would automatically turn to be falsy. You might want to use something like: waitForElementToBeRemoved:

await waitForElementToBeRemoved(() => screen.getByText(/loading/, {exact: false}));

Re error 2: pls check if you do not mock NavigationContainer and/or some other part of React Navigation. Also do you have a navigator in your setup e.g. StackNavigator?

If any of the errors persists, then pls create a minimal repro repository, it would be great if it could be based on ours examples/basic example app.

@firasrg
Copy link
Author

firasrg commented Sep 16, 2022

@firas1220 In general using Provider + NavigationContainer should work.

Re error 1: looks like there might be some automatic re-render that happens due to some async action inside the component which is not triggered by explicitly calling fireEvent. BTW follwing code is incorrect:

    await waitFor(() => {
      expect(screenGlobalLoading).toBeFalsy();
    });

As if you got screenGlobalLoading when it was rendered, then as a const it would automatically turn to be falsy. You might want to use something like: waitForElementToBeRemoved:

await waitForElementToBeRemoved(() => screen.getByText(/loading/, {exact: false}));

Re error 2: pls check if you do not mock NavigationContainer and/or some other part of React Navigation. Also do you have a navigator in your setup e.g. StackNavigator?

If any of the errors persists, then pls create a minimal repro repository, it would be great if it could be based on ours examples/basic example app.

Hello @mdjastrzebski 👋 I really appreciate these suggestions. I do have some questions to ask tbh, but first, as I agree to share a minimal example that would be useful for sure, Im going to built and share the link to it.

Please stay close 🙏

thanks in advance

@firasrg
Copy link
Author

firasrg commented Sep 18, 2022

Hi again @mdjastrzebski ! After a hard work 😤 trying to clear up code in order to extract a minimal sample. Finally, here it is.

BTW, I solved the issue with provider + navigation ✔️. Now, the problem is still with that act() error(s).

Following what you said, I used this :

await waitForElementToBeRemoved(() => screen.getByText(/loading/, {exact: false}));

So now I got this error:

 console.error
    Warning: You called act(async () => ...) without await. This could lead to unexpected testing behaviour, interleaving multiple act calls and mixing their scopes. You should - await act(async () => ...);

Also, I even get act error whithout that line, with the following code:

const reduxRef = createApiStore(apiInstance, {item: itemSliceReducer})

describe('list screen tests', () => {

  // scenario one : initialize screen
  it('list initialization', async () => {

    // wrap into bottom tab navigator and navigation container
    const ComponentToRender = () => (
        <NavigationContainer>
          <SecuredBottomTabNavigator/>
        </NavigationContainer>
    )

    // wrap inside react-redux provider
    render(<ComponentToRender/>, {wrapper: reduxRef.wrapper});

    // get 1st screen (NOT items screen)
    const screenDashboardText = await screen.getByText(/Dashborad/, {exact: false});
    expect(screenDashboardText).not.toBeFalsy();

    // go to items screen!
    const toClick = await screen.findByText('Items');
    fireEvent(toClick, 'press'); // I got act() error here
    
    // await waitForElementToBeRemoved(async () => await screen.findByText('Loading ...'));
    
  });
});

NOTE: The test passes even with that act error. Which is weard :/

Please help. 🏳️

@firasrg
Copy link
Author

firasrg commented Sep 20, 2022

Hi 😃 is there anything wrong my latest msg? I don't get it, why I don't receive some help here ? is it delicate that much? Please HELP I really need this. 😭

@thymikee
Copy link
Member

Hey @firas1220. I'd like to make it clear, that this is not really a help forum, but an issue tracker. We have some dedicated capacity to look at the issues, but it's limited. Please be patient and try reaching out on StackOverflow or on Discord https://discord.com/channels/426714625279524876/497332049187962892 to increase your chances of getting help :)

@firasrg
Copy link
Author

firasrg commented Sep 21, 2022

Hi @thymikee and thanks for reploying:

I'd like to answer on your msg, by spliting it into pieces, that would help both of us; I guess!

You said:

Hey @firas1220. I'd like to make it clear, that this is not really a help forum, but an issue tracker.

My answer:

I think you're wrong, because for me it looks like an issue. As I did followed the guide on act and example(s), even the troubleshooting guide with high care & in different ways. However, I'm still getting annoying error(s) 🤦‍♂️. That means, there is something not ok. I tried to troubleshoot by myself and even asked the community (Reactiflux and Expo Developers), and I'm still stuck. I need some assistance from reliable people and I see this the best place!


You said:

Please be patient and try reaching out on StackOverflow or on Discord https://discord.com/channels/426714625279524876/497332049187962892 to increase your chances of getting help

My answer:

I love patience! Just wondering how long should I wait approximately (days/months/years)? That way, I could know if staying here will help or not. 😅

Btw the link to discord channel is not working. It doesn't bring to anywhere. maybe an invitation will be better.

As for Stackoverflow, that will be my last card.

@thymikee
Copy link
Member

Try using the one we have in the readme: https://discord.gg/QbGezWe

There's something in the works regarding these warnings (they're warnings, not errors, feel free to ignore them really): #1131

@firasrg
Copy link
Author

firasrg commented Sep 21, 2022

Thank @thymikee ! Do I consider this issue closed/resolved then?! 🤔

@thymikee
Copy link
Member

Let's see how #1131 evolves

@firasrg
Copy link
Author

firasrg commented Sep 21, 2022

Right! I close this.

See you there 😉

@firasrg firasrg closed this as completed Sep 21, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants