React-hooks-testing-library: Global `unmountAll` functionality

Created on 17 May 2019  路  7Comments  路  Source: testing-library/react-hooks-testing-library

I have an effect that uses setInterval. In order for my tests to work right, I need to unmount so the interval gets knocked away.

I have code like this:

let globalUnmount;

// I use this is all of my tests to run render the hook
async function runEffects(wait = true) {
  const { result, unmount } = renderHook(() =>
    useMyHookWithIntervals()
  );

  globalUnmount = unmount;
  return {
    result
  };
}
afterEach(() => {
  if (globalUnmount) {
    globalUnmount();
    globalUnmount = null;
  }
});

Is this the expected paradigm? Is this an example that would be good for docs? Is this horrible?

enhancement good first issue question

Most helpful comment

A quick workaround for me was to create a small wrapper and use only this for the tests

//  './renderHook.js';
import {renderHook} from '@testing-library/react-hooks';

let unmounts = [];

export const cleanup = () => {
  unmounts.forEach(unmount => unmount());
  unmounts = [];
};

export default (...args) => {
  const rendered = renderHook(...args);
  unmounts = [...unmounts, rendered.unmount];
  return rendered;
};

import {cleanup as cleanupHooks} from './renderHook';
afterEach(cleanupHooks);

All 7 comments

We have the same problem. When this library moved to react-test-renderer, the cleanup function was removed. This is fine when you are just testing rendering, but a big part of hooks is side effects. There doesn't seem to be a great way to have a global unmount and we are currently stuck on v0.4.1.

@userbq201 if you are trying to report a bug, you should probably open a different ticket. This ticket is not about a bug, just about how to best use what features are available.

Hey, sorry I've been a bit quiet. I've been moving interstate so my spare time has been a bit light on, but I'm here now.

To be honest, an unmountAll is not something I've considered. The snippet you've provided would be a sensible way to do it with the current API.

If anyone wants to implement something like that and submit a PR, I think it would be a useful addition to the library. It would need to track each rendered hooks and unmount all of them, unlike this snippet which only unmounts the last rendered hook, but that should not be too difficult.

Just wondering if this should be called unmountAll or if we bring back cleanup to give us room to add more cleanup steps in the future?

I like how jest has the different levels of clear vs reset mocks and whatnot. So being specific now, and allowing for other specific cleanup steps in the future would seem good. Then we can always have a cleanup that combines all as needed.

A quick workaround for me was to create a small wrapper and use only this for the tests

//  './renderHook.js';
import {renderHook} from '@testing-library/react-hooks';

let unmounts = [];

export const cleanup = () => {
  unmounts.forEach(unmount => unmount());
  unmounts = [];
};

export default (...args) => {
  const rendered = renderHook(...args);
  unmounts = [...unmounts, rendered.unmount];
  return rendered;
};

import {cleanup as cleanupHooks} from './renderHook';
afterEach(cleanupHooks);

I'd be happy with more-or-less the same approach to be done as a PR (renderHook would push the unmount internally though, instead of a wrapper).

Was this page helpful?
0 / 5 - 0 ratings