algolia / react-instantsearch

⚡️ Lightning-fast search for React and React Native applications, by Algolia.
https://www.algolia.com/doc/guides/building-search-ui/what-is-instantsearch/react/
MIT License
1.97k stars 386 forks source link

Question: How to test? #3609

Closed bramski closed 1 year ago

bramski commented 2 years ago

Hey react-instantsearch,

We have a number of components utilizing the hooks to build our app. We are using '@testing-library/react' to test our react app.

What is the best method for setting up mock data to be returned from the hooks? Currently we are doing like so in jest...

import { useRefinementList, useCurrentRefinements } from 'react-instantsearch-hooks-web';
...
jest.mock('react-instantsearch-hooks-web');

describe('My component ', () => {
  afterEach(() => {
    jest.clearAllMocks();
  });

  beforeEach(() => {
    const useRefinementListMocked = jest.mocked(useRefinementList);
    useRefinementListMocked.mockReturnValue({
      items: mlRefinementListMockData,
      refine: jest.fn(),
      canRefine: false,
      canToggleShowMore: false,
      createURL: jest.fn(),
      hasExhaustiveItems: false,
      isFromSearch: false,
      isShowingMore: false,
      sendEvent: jest.fn(),
      searchForItems: jest.fn(),
      toggleShowMore: jest.fn(),
    });
    const useCurrentRefinementsMocked = jest.mocked(useCurrentRefinements);
    useCurrentRefinementsMocked.mockReturnValue({
      canRefine: false,
      createURL: jest.fn(),
      items: mlCurrentRefinementsMockData,
      refine: jest.fn(),
    });
  });

  it('renders', async () => {
    render(
        <MyComponent />
    );
   // expect things
  });

Is this how we're expected to test, by mocking the internals? Is there a provider I can override to pass the data instead so I don't have to use jest mocks?

Thanks!

Haroenv commented 2 years ago

It depends on what you want to test, but a mocked search client with a real wrapper of InstantSearch is how we test in this codebase itself. You can see it for example here:

https://github.com/algolia/react-instantsearch/blob/4ca71ce9e77df440482ce1356a5a6f1720af6d6c/packages/react-instantsearch-hooks-web/src/widgets/__tests__/RefinementList.test.tsx#L14-L120

bramski commented 2 years ago

Wow! That is incredibly helpful. There are a ton of test helpers in there which would be excellent to get exported. Do you plan on writing a testing guide?

bramski commented 2 years ago

Hmm, yeah after spending an hour or two attempting to use this... I don't know enough about the internals to build a good testing harness. In the example above, i was using useCurrentRefinements hook to simulate a certain set of refinements. Can you tell me how I can replace that example with the searchClient mock as you have described? I'm not sure how to go from the fragments to getting items back from useCurrentRefinements

Haroenv commented 2 years ago

To simulate refinements set by the user, you can use initialUiState on the InstantSearch component with the refinements you want to show up, so that would look like this for example:

https://codesandbox.io/s/eloquent-dew-d1hepp?file=/App.tsx

Is that what you're looking for?

In the past we've mainly seen people not testing the components as they're third-party, but if you have a nice setup after these explorations, it would indeed be quite interesting to write a testing guide

sarahdayan commented 1 year ago

I'm moving this to GitHub Discussions as this is not a bug.