-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Open
Description
Bug description
Trying to mergeDeep
with mocks from jest-mock-extended leads to strange behavior:
import { mergeDeep } from 'immutable';
import { mock } from 'jest-mock-extended';
describe('immutable + jest-mock-extended', () => {
test('mergeDeep', () => {
const myMock = mock();
const merged = mergeDeep({ myMock }, { myMock });
console.log(merged.myMock); // undefined!
expect(merged.myMock).toBe(myMock); // fails because merged.myMock is undefined
});
});
Cause
It seems that the various isImmutable
functions (e.g isCollection
) make their assertion on "symbols" like so:
function isImmutable(obj) {
return new Boolean(obj && obj[SYMBOL]);
}
The problem is with the obj[SYMBOL]
assertion, which will return true
for any truthy value, and not necessarily what the package set as value (a literal true
).
Now, the mocks from jest-mock-extended
seem to return a Proxy that, if a key on the object is accessed, the proxy populates that key with a function (which is truthy):
test('isImmutable', () => {
const myMock = mock();
isImmutable(myMock);
console.log(myMock); // it now has `'@@__IMMUTABLE_ITERABLE__@@': [Function: mockConstructor] { ... }` property
});
This makes the package think that the original values (the mocks) given to mergeDeep
originated from the package, which likely messes up with its logic. I'm assuming this will affect other methods as well.
Potential solutions
- Perform a more strict check on the value of the "symbol" (
=== true
or even=== SOME_UNIQUE_SYMBOL
). - Change the symbol check to
obj.hasOwnProperty(SYMBOL)
, which will not "trigger" the auto population of the mock proxy.
Metadata
Metadata
Assignees
Labels
No labels