Skip to content

Testing Async Hooks #285

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

Closed
helabenkhalfallah opened this issue Feb 8, 2019 · 5 comments
Closed

Testing Async Hooks #285

helabenkhalfallah opened this issue Feb 8, 2019 · 5 comments

Comments

@helabenkhalfallah
Copy link

helabenkhalfallah commented Feb 8, 2019

I want to test UsersList with call an async hooks fetch :

// functional component
const UsersList = ({ onItemSelected, }) => {
  // async service fetch hooks
  const url = 'service-url';
  const { error, loading, data, } = **useService**(Service, url, {
    amount: 0,
  });
  return (
    <Fragment>
      <div className="user-list">
          {
            data.map(user => (
              <UserItem
                key={user.id}
                user={user}
                onItemSelected={onItemSelected}
              />
            ))
          }
        </div>
    </Fragment>
  );
};
// async data fetcher HOC
function **useService**(Service, url, params) {
  // service query
  const {
    query,
  } = Service;

  // define internal state
  const [
    error,
    setError,
  ] = useState(null);
  const [
    loading,
    setLoading,
  ] = useState(true);
  const [
    data,
    setData,
  ] = useState(null);

  // execute service
  useEffect(() => {
    query(
      url,
      params,
      ((response) => {
        setData(response);
        setLoading(false);
      }),
      ((serviceError) => {
        setError(serviceError);
        setLoading(false);
      })
    );
  }, []);

  return {
    error,
    loading,
    data,
  };
}

export default useService;
  // query
  // await response of users fetch call
  const url = `url`;
  const response = await axios.get(url, queryParams(params));

  // return result
  return response;

Test :

// mock axios call
jest.mock('axios');

**Case 1:**
it('Should Mount Component & Display Data', async () => {
    axiosMock.get.mockResolvedValue(UserListMock);
    const { getByTestId, getByText, getByPlaceholderText, container, } = render(<UsersList />);
    const titleNode = await waitForElement(() => getByTestId('header-title'));
    expect(titleNode).toHaveTextContent('test');
});

**Case 2:**
it('Should Mount Component & Display Data', async () => {
    let result;
    axiosMock.get.mockResolvedValue(UserListMock);
    act(() => {
      result = render(<UsersList />);
    })
    const { getByTestId, getByText, getByPlaceholderText, container, } = result;
    const titleNode = await waitForElement(() => getByTestId('header-title'));
    expect(titleNode).toHaveTextContent('test');
});

But I got :

1/ always

    act(() => {
      /* fire events that update state */
    });
    /* assert on the output */

2/ titleNode always null.

How should be my test to test Component = UI + Hooks ?
How to await for useService Hooks to end ?

Thanks :)

@kentcdodds
Copy link
Member

Hi @helabenkhalfallah,

We're still trying to figure out the best way to avoid that new warning in React 16.8.0

I'm going to go ahead and close this in favor of our existing discussion: #281

As well as the discussion on React: facebook/react#14769 (this is not really a react-testing-library issue).

@helabenkhalfallah
Copy link
Author

Hello @kentcdodds OK, but I have two issues :(
titleNode always null.

@helabenkhalfallah
Copy link
Author

// mock axios call
jest.mock('axios');

**Case 1:**
it('Should Mount Component & Display Data', async () => {
    axiosMock.get.mockResolvedValue(UserListMock);
    const { getByTestId, getByText, getByPlaceholderText, container, } = render(<UsersList />);
    const titleNode = await waitForElement(() => getByTestId('header-title'));
    expect(titleNode).toHaveTextContent('test');
});

**Case 2:**
it('Should Mount Component & Display Data', async () => {
    let result;
    axiosMock.get.mockResolvedValue(UserListMock);
    act(() => {
      result = render(<UsersList />);
    })
    const { getByTestId, getByText, getByPlaceholderText, container, } = result;
    const titleNode = await waitForElement(() => getByTestId('header-title'));
    expect(titleNode).toHaveTextContent('test');
});

titleNode always null.

@kentcdodds
Copy link
Member

Hi @helabenkhalfallah,

Could you ask this on the official community support channel please? https://spectrum.chat/react-testing-library

Thanks, and good luck!

@helabenkhalfallah
Copy link
Author

OK thank you :) :)

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

2 participants