styled-components: 3.2x Breaking Jest/Enzyme tests of components that mount elements using unstable_RenderSubtreeIntoContainer
Jest/enzyme tests that were passing until 3.2x release are now failing once 3.2x is installed. Reverting to 3.1.6 solves the issue.
Non-passing Environment
System:
- OS: macOS High Sierra 10.13.3
- CPU: x64 Intel® Core™ i7-4770HQ CPU @ 2.20GHz
- Free Memory: 1.41 GB
- Total Memory: 16.00 GB
- Shell: /bin/zsh - undefined
Binaries:
- Node: 7.10.0
- Yarn: 0.23.3
- npm: 4.2.0
- Watchman: 4.7.0
npmPackages:
babel-jest:
- wanted: ^20.0.3
- installed: 20.0.3
babel-plugin-styled-components:
- wanted: ^1.3.0
- installed: 1.5.1
enzyme:
- wanted: ^2.7.1
- installed: 2.9.1
jest:
- wanted: ^20.0.4
- installed: 20.0.4
styled-components:
- wanted: ^3.0.0
- installed: 3.2.2
Passing Environment
System:
- OS: macOS High Sierra 10.13.3
- CPU: x64 Intel® Core™ i7-4770HQ CPU @ 2.20GHz
- Free Memory: 1.47 GB
- Total Memory: 16.00 GB
- Shell: /bin/zsh - undefined
Binaries:
- Node: 7.10.0
- Yarn: 0.23.3
- npm: 4.2.0
- Watchman: 4.7.0
npmPackages:
babel-jest:
- wanted: ^20.0.3
- installed: 20.0.3
babel-plugin-styled-components:
- wanted: ^1.3.0
- installed: 1.5.1
enzyme:
- wanted: ^2.7.1
- installed: 2.9.1
jest:
- wanted: ^20.0.4
- installed: 20.0.4
styled-components:
- wanted: 3.1.6
- installed: 3.1.6
Reproduction
I am unable to share the code in which I found this behavior, but can create a repo to repro if needed.
Steps to reproduce
Using React 15x, create a component that has a child that is rendered via unstable_renderSubtreeIntoContainer
, write test using enzyme’s mount
. Tests pass with version 3.1.6
but fail under version(s) 3.2x
.
Expected Behavior
Tests don’t break due to warning from styled-components
that DOM node mounted with unstable_renderSubtreeIntoContainer
is unmounted. Tests pass with 3.1.6 but do not with
Actual Behavior
Tests break with this sample output (where Feedback.js.jsx
is a child of the mounted component that uses unstable_renderSubtreeIntoContainer
) when moving from 3.1x to 3.2x:
FAIL app/__tests__/dashboard_test.js
● Test suite failed to run
Trying to insert a new style tag, but the given Node is unmounted!
- Are you using a custom target that isn't mounted?
- Does your document not have a valid head element?
- Have you accidentally removed a style tag manually?
at makeStyleTag (node_modules/styled-components/dist/styled-components.cjs.js:510:13)
at makeTag (node_modules/styled-components/dist/styled-components.cjs.js:818:14)
at StyleSheet.makeTag$$1 [as makeTag] (node_modules/styled-components/dist/styled-components.cjs.js:1045:12)
at StyleSheet.getTagForId (node_modules/styled-components/dist/styled-components.cjs.js:1063:18)
at StyleSheet.deferredInject (node_modules/styled-components/dist/styled-components.cjs.js:1103:10)
at new ComponentStyle (node_modules/styled-components/dist/styled-components.cjs.js:1963:27)
at createStyledComponent (node_modules/styled-components/dist/styled-components.cjs.js:1808:26)
at templateFunction (node_modules/styled-components/dist/styled-components.cjs.js:2076:14)
at Object.<anonymous> (app/components/feedback.js.jsx:15:116)
at Object.<anonymous> (app/components/dashboard.js.jsx:12:19)
at Object.<anonymous> (app/__tests__/dashboard_test.js:9:20)
at handle (node_modules/worker-farm/lib/child/index.js:44:8)
at process.<anonymous> (node_modules/worker-farm/lib/child/index.js:51:3)
at emitTwo (events.js:106:13)
at process.emit (events.js:194:7)
at process.nextTick (internal/child_process.js:766:12)
at _combinedTickCallback (internal/process/next_tick.js:73:7)
at process._tickCallback (internal/process/next_tick.js:104:9)
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Comments: 23 (6 by maintainers)
Here is how I solved it: I created a mock file for
styled-components
__mocks__/styled-components.js
Styled-Components:
3.3.2
Jest:23.6.0
We run into the same issue with
jest.mock
calls in test module causingTrying to insert a new style tag, but the given Node is unmounted!
error.Resolved the issue by changing our mocks from this
to this:
Chiming in…we have a fairly large collection of styled components in our application (~1000 off of a quick search) tested with jest 23 using
v3.1.4
. Upgrading tov3.3.2
triggered the above error in a few of our test files:For us, the error actually seems to get thrown before any test cases are run. We were able to get past the error by un-mocking certain modules, but the stack trace indicates that modules containing styled component declarations are being imported/evaluated during test setup, before the DOM environment is initialized (possibly as a result of how jest handles mocking?). (The
styled-components
specific stack trace looks very similar to the OP).@kitten Your workaround did the trick for us, but hoping you might be able to shed some light on why this is happening. Noting the
StyleSheet
rewrite from3.1.x
to>3.2
, did the point at which styles get injected into the document change?Here’s the snippet added to our test initialization, pulled from your comments. Based on my understanding we’re now using the server stylesheet instead of the DOM based one.
Happy to connect and provide more info if it would be helpful!
If anyone else runs into these problems… another solution that seem to work is to force styled-components to use server side rendering in your tests.
It can be done by adding this to one of the files you have specified in your
jest.config.js
assetupFilesAfterEnv
.The
true
is assigned toforceServer
variable. This must run before the imports in tests (it’s not enough to put it to test itself).I combined the answers, I put the stylesheet reset of the comment above in
__mocks__/styled-components.js
and return the original.I can reliably reproduce this.
jest@20.0.4
react@16.4.2
styled-components@3.3.3
. Upgrading to jest@23.4.2 gives a different (unrelated) error.This is what I did to reproduce it. If you are trying to reproduce this, please use the files exactly as below. There are many things that I would expect to have no effect that actually do.
test.js
test2.js
Running
jest test.js
produces the followingI am going to keep looking into how to fix this, but perhaps this may help others track it down faster than I.
hm… render props shouldn’t be a problem, we hardly use them. It’s a problem how many style rules are allowed in development mode. Enzyme somehow cleans DOM if it gets too big and this removes some previous styles and breaks SC. I don’t know what is the best option here… allowing to bump this limit or somehow force enzyme not to clean DOM every time.
we were able to bypass this problem by setting
NODE_ENV=production
in npm script. if this solves the problem, can we opt-in this limit for development?Actually, I have a hypothesis. It might be that a jsdom environment in enzyme and jest resets the head element, without styled-components being reset.
In 3.2 we’re now attempting to keep all elements together. So we’re appending to the last style tag’s parent and are inserting the new style tag after the last.
So knowing that, maybe a reset will do it. Can you try the following for me please?
(Also don’t worry, you’ll only be haunted by spooky and funny ghosts 👻)
Looking at the output more closely, the “Several Instance” warning mentioned in this issue: https://github.com/styled-components/styled-components/issues/1592 is also being thrown for these tests (the warning terminal output got overwritten initially). So this issue may be related to Jsdom/jest setting multiple instances of
styled-components
.