Reputation: 1598
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
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