Sergio Mazzoleni
Sergio Mazzoleni

Reputation: 1598

deal when several extended matchers with same name

I am using custom matchers from two external libraries jest-dom/extend-expect and jest-extended. Both libraries defines a matcher named toBeEmpty, but with different behaviour. One expects a string/array/object/iterable to be empty, the other expects a DOM element to be empty.

My feeling is that the order in jest configuration impacts which matcher is actually used in test:

    setupFilesAfterEnv: [
        '@testing-library/jest-dom/extend-expect',
        'jest-extended',
    ],
    setupFilesAfterEnv: [
        'jest-extended',
        '@testing-library/jest-dom/extend-expect',
    ],

With first config, jest-extended version takes precedence, while with the second one, the jest-dom version wins. Is this correct?

Is there a way to use both matchers? Should it be the library author to detect that another matcher already exists and deal with it?

Upvotes: 1

Views: 240

Answers (1)

Estus Flask
Estus Flask

Reputation: 222503

expect.extend merges matchers into matcher object, matchers with same names are being replaced without a notice, this is a known problem.

A way to prevent name collisions is to provide namespaces for matchers and set them in Jest setup file specified in setupFilesAfterEnv. Matcher functions can be imported directly from matcher libraries and supplied to expect.extend.

@testing-library/jest-dom provides public entry point to import matchers:

const domMatchers = require('@testing-library/jest-dom/matchers');
const namespacedDomMatchers = Object.fromEntries(
  Object.entries(domMatchers).map(([name, matcher]) => [`dom_${name}`, matcher])
);

expect.extend(namespacedDomMatchers);

jest-extended has internal module that can be imported as well:

const extendedMatchers = require('jest-extended/dist/matchers');
const namespacedExtendedMatchers = Object.fromEntries(
  Object.entries(extendedMatchers).map(([name, matcher]) => [`extended_${name}`, matcher])
);

expect.extend(namespacedExtendedMatchers);

Matchers from both libraries become available as dom_toBeEmpty and extended_toBeEmpty.

Upvotes: 1

Related Questions