albertogasparin/react-magnetic-di

Track used and unused mocks

Closed this issue · 2 comments

There is a general problem with mocking - it can be only added.

  • Let's imagine you have a component doing something
  • You create a test for it...
    • and test fails
  • You add a mock
    • and test passes
  • Time goes by, component got refactored a few time
    • but the no longer required mock is still here

– A short story "How I met code erosion"


Desired goal: be notified about missing mocks as well as no longer required ones.

Proposal: implement tracking of injectable usage:

  • verify that every injected got di-ed.
    • Will reduce wtf-factor of missed di(if eslint by any reason is not working). Still happening once-twice a week in my team.
  • verify that some injected functions(only) got executed
    • is totally a jest responsibility, but magnetic should guide which injectables expected.toHaveBeenCalled and which are not.
    • not all injectables should be executed, there are cased for di-ing something on environment level (intl), or some tests where stuff is excepted not to be called.

I am not sure that Magnetic can do what is required due to the need of integration with the test runner, or at least with stubs (aka jest.fn). Thus desired goal might be achievable only by building an abstraction on top of Magnetic.

Deciding what should be build inside Magnetic and what should be outside - is the task for this issue.

We could probably expose a stats API:

import { stats } from 'react-magnetic-di'

afterEach(() => {
  if (stats.unused().length > 0) {
    const [original, injectable] = stats.unused()[0];
    throw new Error('Unused injectable ${injectable.displayName} (for ${original.name})')
  }
  stats.reset();
})

We will need integration with the test runner if we want accurate stats, but that would be flexible enough to handle the global scope.

If test helpers have a function like renderWithDi then such check can be integrated inside it. This will be enough to cover all injectables which were di-ed in component, even if they were not used, which is a problem of component, not test harness.

This will create a problem for components displayed after reaching a condition (click) and so there should be an ease escape hatch for such very rare cases.